[ php / escape_string / 보안 / 해킹 ] SQL injection 예방법
[ php / escape_string / 보안 / 해킹 ] php SQL injection 예방법
magic_quote_gpc
Sets the magic_quotes state for GPC (Get/Post/Cookie) operations. When magic_quotes are on, all ' (single-quote), " (double quote), \ (backslash) and NUL's are escaped with a backslash automatically.
이것은 자동으로 addslashes() 를 하는 옵션입니다.
하지만 sql 문법에 완전히 맞지 않습니다.
물론 \ 로 escape 하는 문법을 지원해 주긴 합니다만, 원래의 문법은 아닙니다.
게다가 ; 는 escape 시키지 않으니 사소한 실수로 큰 보안구멍이 발생할 수 있습니다.
*_escape_string()
각 sql 별로 escape_string() 이라는 함수가 제공됩니다.
mysql_escape_string('문자열') 로 mysql 에 맞는 escape 된 문자열로 변환해 줍니다.
일반적으로 sql 의 문법은 문자열을 작은따옴표(') 로 묶고, 작은따옴표를 표현하는것은 작은따옴표 2번 입니다.('')
이것 '참' 좋군 이라는 문자열을 escape 시킨다면 이것 ''참'' 좋군 이 되고 query('INSERT INTO table VALUES (\'이것 \'\'참\'\' 좋군\');') 이 될 것입니다.
보통은 post 받은 문자열을 db 에 넣을 것이므로
$_POST = array_map('mysql_escape_string', $_POST); 로 한번에 escape 시키고 사용하면 됩니다.
주의할 것은 select 한 결과를 그대로 재사용할 때 다시 escape 시켜야 한다는 것입니다.
result 는 escape 되지 않은 문자열 입니다.
prepared query
좀더 안전하고 편리한 방법으로 prepared query 를 이용하는 방법이 있습니다.
INSERT INTO table (a, b) VALUES (:a, :b) 라는 쿼리를 미리 prepare (컴파일?) 시킵니다.
이 단계에서는 인젝션이 일어날 문자열이 아예 포함되지 않은채 prepare 됩니다.
그 다음 prepare 된 쿼리에 문자열을 bind 하여 쿼리를 실행합니다.
bind 단계에서는 파싱하지 않으므로 escape 시키지 않아도 안전합니다.
mysqli, pg 등이 제공하고, PDO 를 이용하면 손쉽게 적용할 수 있습니다.
$db = new PDO(접속);
$stmt = $db->prepare('INSERT INTO table (a, b) VALUES (:a, :b)');
$fields[':a'] = '\'; DELETE FROM table;\';
$fields[':b'] = '\'; DELETE FROM table;\';
$stmt->execute($fields);
bind 값인 :a, :b 는 문자열이든 수이든 따옴표를 쓰지 않습니다.
위의 예제 외에 bindParam() 함수를 이용하여 & 참조변수로 만들어 변수에 값만 채우고 execute() 하면 되는 방식도 있습니다.
어떻게 뚫을 수 있지? 아무리 생각해도 이 코드에서는 뚫을 수 없어. 그러니 귀찮게 escape 안시켜도 돼.
오만입니다. 개인의 생각에는 한계가 있고, 뚫린 후에는 늦습니다.
escape 는 프로그래머의 기본 예절 입니다.
magic_quote_gpc
Sets the magic_quotes state for GPC (Get/Post/Cookie) operations. When magic_quotes are on, all ' (single-quote), " (double quote), \ (backslash) and NUL's are escaped with a backslash automatically.
*_escape_string()
*_escape_string()
각 sql 별로 escape_string() 이라는 함수가 제공됩니다.
mysql_escape_string('문자열') 로 mysql 에 맞는 escape 된 문자열로 변환해 줍니다.
일반적으로 sql 의 문법은 문자열을 작은따옴표(') 로 묶고, 작은따옴표를 표현하는것은 작은따옴표 2번 입니다.('')
이것 '참' 좋군 이라는 문자열을 escape 시킨다면 이것 ''참'' 좋군 이 되고 query('INSERT INTO table VALUES (\'이것 \'\'참\'\' 좋군\');') 이 될 것입니다.
보통은 post 받은 문자열을 db 에 넣을 것이므로
$_POST = array_map('mysql_escape_string', $_POST); 로 한번에 escape 시키고 사용하면 됩니다.
주의할 것은 select 한 결과를 그대로 재사용할 때 다시 escape 시켜야 한다는 것입니다.
result 는 escape 되지 않은 문자열 입니다.
prepared query
prepared query
좀더 안전하고 편리한 방법으로 prepared query 를 이용하는 방법이 있습니다.
INSERT INTO table (a, b) VALUES (:a, :b) 라는 쿼리를 미리 prepare (컴파일?) 시킵니다.
이 단계에서는 인젝션이 일어날 문자열이 아예 포함되지 않은채 prepare 됩니다.
그 다음 prepare 된 쿼리에 문자열을 bind 하여 쿼리를 실행합니다.
bind 단계에서는 파싱하지 않으므로 escape 시키지 않아도 안전합니다.
mysqli, pg 등이 제공하고, PDO 를 이용하면 손쉽게 적용할 수 있습니다.
$db = new PDO(접속);
$stmt = $db->prepare('INSERT INTO table (a, b) VALUES (:a, :b)');
$fields[':a'] = '\'; DELETE FROM table;\';
$fields[':b'] = '\'; DELETE FROM table;\';
$stmt->execute($fields);
bind 값인 :a, :b 는 문자열이든 수이든 따옴표를 쓰지 않습니다.
위의 예제 외에 bindParam() 함수를 이용하여 & 참조변수로 만들어 변수에 값만 채우고 execute() 하면 되는 방식도 있습니다.
어떻게 뚫을 수 있지? 아무리 생각해도 이 코드에서는 뚫을 수 없어. 그러니 귀찮게 escape 안시켜도 돼.
'Web-Programming' 카테고리의 다른 글
디버그 툴 : Debug Tools - debugbar-v5.4.1, Firebug 1.5.3 (0) | 2011.10.08 |
---|---|
[무료 에디터 다운로드] 자바스크립트 DHTML 이지 에디터 (1) | 2011.08.27 |
[ 보안 / 인젝션 공격 / 해킹 / 스크립트 / php / asp / jsp ] SQL injection 해킹 보안 (0) | 2011.04.04 |
[ 웹 프로그래머 / 디버그 툴 / developer toolbar / http watch / fiddler2 ] 웹 프로그래머 디버그 툴 TOP 6 (0) | 2011.03.15 |
MYSQL - 서브 쿼리 (1) | 2011.01.05 |
IE-익스플로러 에서만 사용되게 하는 소스 (0) | 2011.01.05 |
jQuery - 제이쿼리 란?? (0) | 2010.06.28 |
아파치 REWRITE 모듈 - 웹 사이트 주소를 짧게 써보자!! (0) | 2010.05.28 |
자바스크립트, 스타일시트 탭 메뉴 (0) | 2010.05.23 |
Query style menu with CSS3 : 제이쿼리 스타일 스타일시트 메뉴바, 네비게이션바 (0) | 2010.05.12 |
댓글