본문 바로가기
코드이그나이터와 php7와 mysql

해킹을 막아라! MySQL인젝션 보안

1. 오토셋 APM 인스톨러 ( apache + php7.2 + mariadb ) 설치 | https://itadventure.tistory.com/93

2. 코드이그나이터 4 ( codeigniter 4 ) 설치 | https://itadventure.tistory.com/95

3. 비주얼 스튜디오 코드 에디터 설치 & 한글 설정 | https://itadventure.tistory.com/96

4. 폴더열기 / 웹페이지 편집(1) | https://itadventure.tistory.com/97

5. 웹페이지 편집(2) | https://itadventure.tistory.com/101

6. 코드이그나이터4의 URL 규칙 | https://itadventure.tistory.com/105

7. php, 네임스페이스 [ namespace ] ?! | https://itadventure.tistory.com/118

8. 코드이그나이터의 네임스페이스, 그리고 모델 | https://itadventure.tistory.com/122

9. 코드이그나이터 뷰의 파라미터 전달 | https://itadventure.tistory.com/147

10. 코드이그나이터 뷰를 나눠 볼까요? | https://itadventure.tistory.com/174

11. MYSQL 이 뭐여? [ 마이에스큐엘은 서류철이다! ] | https://itadventure.tistory.com/175

12. MYSQL 콘솔에 접속해보자! | https://itadventure.tistory.com/178

13. MySql에 넣었다가 꺼냈다가, 뭘? | https://itadventure.tistory.com/265

14. 검색진열대 MYSQL | https://itadventure.tistory.com/267

15. 편집의 왕자 MySQL | https://itadventure.tistory.com/269

16. 코드이그나이터4, MYSQL과 손잡다. | https://itadventure.tistory.com/271

17. MySQL -> 컨트롤러 -> 뷰 트리플 패스! | https://itadventure.tistory.com/272

18. 코드이그나이터! MySQL 에 입력하다! ( insert ) | https://itadventure.tistory.com/273

19. 해킹을 막아라! MySQL인젝션 보안


시큐리티! ( Security )
'보안'이라는 뜻인데요.

가끔 뉴스를 통해 접해 들어보시는 소리,
'보안이 뜷였다', '보안이 취약하다', '모 대학생이 해킹을 시도하여..'는 말들을 많이 들어보시지요?

무언가 유용한 서비스를 만들어 제공할 수 있는 웹은 
별도의 프로그램을 추가로 설치하지 않아도 사용할 수 있는 자유로운 장점이 있는 반면,
웹의 취약점을 파고들어 정보를 빼내거나, 데이터를 조작하는 등의 크랙킹(Cracking)이 가능한 단점이 있습니다.

국내에서는 이를 '해킹(Hacking)'이라고도 합니다.

본 챕터에서는 전문적인 수준의 해킹은 아니지만,
지난 시간에 다루었던 addslashes 명령문을 이용하여 초급 수준의 해킹을 막는 방법을 소개하고자 합니다.

아래 2가지 소스 코드의 차이점을 잠깐 보도록 하겠습니다. 

첫번째 소스 코드는 아래와 같고,

$db->query("insert into book set
    title='".$title."',
    body='".$body."',
    totalpage='".$totalpage."',
    author='".$author."'");

두번째 소스 코드는 아래와 같습니다.

$db->query("insert into book set
    title='".addslashes($title)."',
    body='".addslashes($body)."',
    totalpage='".addslashes($totalpage)."',
    author='".addslashes($author)."'");

2가지 모두 앞페이지에서 입력받았던 책정보들을 삽입하는 MySQL 쿼리문을 실행하는 명령인데요.
$title, $body, $totalpage, $author 변수가 각각 addslashes( ) 함수로 싸여진 것을 빼고는 동일합니다.

그런데 큰 차이가 있습니다.
바로 두번째 소스코드는 해킹되지 않는다는 이점이 있습니다.

어째서 그럴까요?
그 이유는 해커가 특정 특수문자 조합를 이용해서 해킹을 시도할 수 있기 때문입니다.

첫번째 소스코드의 $title 입력항목에 특수문자조합을 입력하면,

이 소스 코드는

$db->query("insert into book set
    title='".$title."',
      :

아래와 같이 해석됩니다.

$db->query("insert into book set
    title='특수문자조합',
      :

해커는 이 특수문자조합을 이용하여 해킹을 할 수 있는 방법이 있는데요.
어디까지나 해킹을 막는 보안에 관심 있는 분은 유심히 보시길 바랍니다.

※ 주의 ※
결코 이런 쉬운 해킹 수단으로 여기저기 테스트하셨다가 웬만한 사이트는 해킹도 되지 않을 뿐더러
시도한 기록이 서버에 남기 때문에 사이버 수사대에 범죄 접수 의뢰되어 쇠고랑을 찰 수도 있으니 

"절대로 시도하시면 안됩니다."

시도하시더라도 내 PC에 설치된 오토셋에만 테스트할 요령으로만 하시기 바랍니다.

특수문자 조합의 규칙은 아래와 같습니다.

책제목에 코드이그나이터4 라는 제목 대신 
따옴표와 콜론 ( '; ), 그리고 이어서 해킹을 시도할 SQL 명령문을 입력하면 해당 SQL 명령문이 실행이 됩니다.

이를테면 책의 제목을 다음과 같이 입력하는 것입니다.

제목 : ';update book set title='변경';

그러면 앞의 소스가 아래와 같이 해석됩니다.

$db->query("insert into book set
    title='';update book set title='변경';',
      :

그러면 어떤 일이 일어날까요?
2개의 MySQL 명령문이 실행이 됩니다.

첫번째는 다음 명령문이고,

insert into book set title='';

두번째는 다음 명령 문입니다.

update book set title='변경';

그렇다면 의도하지 않게 모든 책의 제목이 '변경'으로 바뀌어 버릴 수 있습니다.
이런 해킹 기술을 SQL Injection 이라고 하는데요.

다행히도 php7 버전에서의 mysql 클래스는 이런 불완전한 입력 형태를 
오류로 인식하여 실행하지 않는 것으로 보입니다.

하지만 낮은 php 버전에서는 mysql 설정이 안되어 있는 경우 이 기술이 통할 수 있기 때문에, 
근본적으로 이런 문제를 방지하기 위해 addslashes 명령문을 이용하여 입력된 파라미터를 감싸는 것입니다.
그 목적 외에도 다른 사유도 있습니다.

일부 특수문자는 MySQL에서 특수목적으로 사용되기 때문에 이러한 특수문자를 기본적으로는 보관할 수 없습니다.

이를테면 2020's 페스티벌 이라는 문장을 addslashes 없이 insert 명령문을 이용, 보관하려면 
오류가 발생합니다.

그 이유는 2020 뒤에 표시되는 따옴표 기호(')가 MySQL 에서 사용하는 기능성 특수문자이기 때문이지요.

이런 경우 이렇게 변환해서 보관해야 합니다. 따옴표 앞에 원화표시를 붙이면 오류가 나지 않습니다.

2020's 페스티벌

=> 2020\'s 페스티벌

그러면 실제 MySQL 테이블에는 어떻게 보관될까요?
정상적으로 2020's 페스티벌 로 보관이 되는 것이지요.

사실 이 기호는 원래 역슬래시 (\) 라는 기호이지만, 
한국에서는 이 기호를 국내 화폐 용도의 문자인 원화(₩) 표시로 활용하고 있어
한글 폰트에서는 이 기호가 원화기호()로 표기되고, 
영문 폰트에서는 동일한 이 기호가 역슬래시(\)로 표기됩니다.

그래서 원래 명칭을 슬래시(/)의 반대 방향, 역슬래시(\)라고 부릅니다.
그래서 addslashes 명령문도 "(역)슬래시 기호를 첨가하라"는 의미의 명령문인 것이지요.

이렇게 역슬래시 기호를 특수문자 앞에 붙여서 insert 명령문을 사용하면
MySQL문에서 오류가 나지 않습니다.

그러면 어떤 특수 기호 앞에 붙여야 할까요?
우리는 그런 고민을 할 필요가 없습니다.
바로 addslashes 함수가 알아서 붙여주니까요.

만약 $title 변수에 2020's 페스티벌 이란 문장이 들어 있다면 
addslashes($title) 은 자동적으로 2020\'s 페스티벌 이란결과를 돌려줍니다.

소스코드에서 해석될 때도
이 소스코드가

$db->query("insert into book set
    title='".addslashes($title)."',
      :

이렇게 오류가 나지 않는 방법으로 해석되는 것이지요.

$db->query("insert into book set
    title='2020\'s 페스티벌',
      :

addslashes() 함수의 사용방법에 대해 도움이 되셨는지요?

어떤 프레임워크의 경우 공통경유파일에서 이러한 addslashes 작업을 사전에 모두 해놓는 경우도 있습니다.
또는 PHP 설정 파일인 php.ini 에서 magic_quotes_gpc 옵션을 on 으로 정할 경우 자동으로 addslashes 를 수행하기도 합니다.
그럴 경우에는 도리어 addslashes() 함수를 사용하면 결과가 이상해기도 하니, 사용하지 않으셔야 합니다.


이번 챕터에서는 추가된 소스 없는 설명뿐이었는데요.
addslashes의 중요성에 대한 이해가 되셨는지 모르겠습니다.

아무쪼록 필요하신 분에게 도움이 되셨으면 합니다.
코로나가 이제 감소세이지만 끝까지 방심하지 마시고 건강관리 잘 하시는 여러분 되시길 바라며,
하나님의 보호하심이 함께 하시기를 소원합니다.

오늘도 여기까지 읽어주신 분들께 감사드립니다 :)