2009-07-22 3 views
77

DB 연결없이 건식 테스트를해야 할 때 데이터베이스에 연결하지 않고 mysql_real_escape_string으로 작동하는 기능을 원합니다. mysql_escape_string은 더 이상 사용되지 않으므로 바람직하지 않습니다. 내 연구 결과의 일부 :DB에 연결하지 않고 mysql_real_escape_string에 대한 대안

http://www.gamedev.net/community/forums/topic.asp?topic_id=448909

http://w3schools.invisionzone.com/index.php?showtopic=20064

+1

+1 MySQL 클래스를 직접 작성하고 매개 변수 바인딩 목적으로 mysql_real_escape_string()을 사용합니다. 나는 mysqli를 사용하는 것을 피한다. 나 또한 다중 파일 및 다중 클래스 라이브러리를 피하십시오. 내가 필요로하는 것은 단정하고 깨끗한 단일 클래스입니다. 고맙습니다! – Viet

+0

http://ca2.php.net/manual/en/function.addslashes.php – mpen

+0

+1. 나의 유스 케이스는 SugarCRM APi로, API를 통해 SQL의 단편을 원격 SugarCRM 인스턴스로 푸시해야한다. 불쾌하지만, 그것이 내가 함께 일해야만하는 것입니다 (SugarCRM 개발자 헤드를 함께 노크하십시오). API를 사용하는 응용 프로그램에서 SQL의 문자열을 이스케이프해야하며 이는 SugarCRM 인스턴스 뒤의 데이터베이스와 완전히 별개입니다. – Jason

답변

64

DB 연결없이 문자열을 안전하게 이스케이프하는 것은 불가능합니다. mysql_real_escape_string() 및 준비된 문은 적절한 문자 집합을 사용하여 문자열을 이스케이프 할 수 있도록 데이터베이스에 연결해야합니다. 그렇지 않으면 멀티 바이트 문자를 사용하여 SQL 주입 공격이 계속 가능합니다.

테스트 인 경우에, 당신은뿐만 아니라 mysql_escape_string()을 사용할 수 있습니다, 그것은 SQL 주입 공격에 대한 보증 100 %는 아니지만, 그것은 DB에 연결하지 않고 안전한 아무것도를 구축하는 것은 불가능하다.

+1

+1 메모를 보내 주셔서 감사합니다. 필자는 멀티 바이트 문자를 사용하여 SQL 주입 공격을 테스트하는 방법을 잘 모릅니다. – Viet

+2

업데이트 할 오래된 코드를 받았습니다. 그것은 연결없이'mysql_escape_string'을 사용합니다 (여전히 그 이유를 찾으려고합니다). 이 함수는 사용되지 않으므로 대체 할 수있는 방법이 궁금합니다. 연결을 열지 않고도 어떤 함수가 그것을 대체 할지라도 "적절한 문자 집합"을 지정할 수있는 것은 당연한 것처럼 보입니다. – JohnK

+0

@ JohnK, 그것은 PHP가 이제까지 호출 될 수있는 한 "정확한"것입니다. :-) $ connection 매개 변수에 대해 : "선택 사항 : MySQL 연결을 지정합니다. 지정하지 않으면 mysql_connect() 또는 mysql_pconnect()에 의해 마지막으로 열린 연결이 사용됩니다." –

53

음, mysql_real_escape_string 함수 참조 페이지에 따라 "는 mysql_real_escape_string()의 MySQL의 라이브러리에 다음과 같은 문자를 이스케이프 함수 인 mysql_real_escape_string 전화 : \의 x00부터 \ n \ R \ ', "및 \의 X1A."염두에두고

, 당신은 당신이 필요로 정확히 무엇을해야합니까 게시 번째 링크에 주어진 기능 :

function mres($value) 
{ 
    $search = array("\\", "\x00", "\n", "\r", "'", '"', "\x1a"); 
    $replace = array("\\\\","\\0","\\n", "\\r", "\'", '\"', "\\Z"); 

    return str_replace($search, $replace, $value); 
} 
+6

감사합니다. "\ x00부터 '=>'\ x00에서 ' "\ n "=>'\ n '을 기능을 탈출 ($ aQuery) { 반환 strtr ($ aQuery, 배열 ( : 나는 다른 무언가를 건의 할 것 ""\ r "=> \ x1a "=> '\ x1a' )); } – Viet

+1

\ x1a가 \\ x1a가 아닌 \\\ x1a로 대체되는 이유는 무엇입니까? 이것은 오타입니까? –

+13

-1 이것은 매우 위험합니다. 데이터베이스 연결이 멀티 바이트 문자 세트를 사용하는 경우 이와 같은 간단한 바이트 대체는 데이터 손상 (이스케이프/인용 문자 포함)을 유발할 수 있습니다. 이는 악의적 인 공격자가 의도적으로 임의의 SQL을 주입 할 수 있습니다. – eggyal

22

다른 답변에 대한 직접적인 반대에서,이 다음 기능은 멀티 바이트 문자로도 안전합니다.

// replace any non-ascii character with its hex code. 
function escape($value) { 
    $return = ''; 
    for($i = 0; $i < strlen($value); ++$i) { 
     $char = $value[$i]; 
     $ord = ord($char); 
     if($char !== "'" && $char !== "\"" && $char !== '\\' && $ord >= 32 && $ord <= 126) 
      $return .= $char; 
     else 
      $return .= '\\x' . dechex($ord); 
    } 
    return $return; 
} 

내가 추가 연구에서 위의 코드는 작동하지 않습니다 왜 자신을 말해 줄 수있는 것보다 더 많은 지식이있는 사람 ...

+0

+1 추가 작업을 보내 주셔서 감사합니다. 필자는 멀티 바이트 관련 SQL 인젝션에 대해 자세히 알아볼 것입니다. – Viet

+0

$ return. = '\ x'여야합니다. dechex ($ ord); 대신 – Viet

+1

일반적으로, 작은 따옴표로 묶은 문자열에서도 '\\'을 사용하는 것을 선호합니다. 조심하지 않으면 단일 '\'가 다음 문자에 영향을 미칠 수 있기 때문입니다. 나는 단지 다시 강박 관념 일뿐입니다. –

5

를 바라고, 나는 발견했습니다

http://dev.mysql.com/doc/refman/5.1/en/news-5-1-11.html

보안 수정 :

다중 바이트 인코딩 처리에서 SQL 주입 보안 홀을 발견했습니다. 서버에 버그가있어 mysql_real_escape_string() C API 함수로 이스케이프 된 문자열을 잘못 파싱했습니다.

이 취약점은 Josh Berkus와 Tom Lane이 OSDB 컨소시엄의 프로젝트 간 보안 공동 작업의 일부로 발견하여보고했습니다. SQL 삽입에 대한 자세한 내용은 다음 텍스트를 참조하십시오.

토론. 멀티 바이트 인코딩 처리에서 SQL 주입 보안 구멍이 발견되었습니다. SQL 주입 보안 구멍은 사용자가 데이터베이스에 삽입 할 데이터를 제공 할 때 사용자가 서버가 실행할 데이터에 SQL 문을 삽입 할 수있는 상황을 포함 할 수 있습니다. 이 취약점과 관련하여 문자 집합 비 인식 이스케이프 (예 : PHP의 addslashes())를 사용하면 일부 멀티 바이트 문자 집합 (예 : SJIS, BIG5 및 GBK)에서 이스케이프를 무시할 수 있습니다. 결과적으로 addslashes()와 같은 함수는 SQL 주입 공격을 방지 할 수 없습니다. 이 문제를 서버 측에서 해결하는 것은 불가능합니다. 가장 좋은 해결책은 응용 프로그램이 mysql_real_escape_string()과 같은 함수가 제공하는 문자 집합 인식 이스케이프를 사용하는 것입니다.

그러나 MySQL 서버가 mysql_real_escape_string()의 출력을 구문 분석하는 방법에서 버그가 발견되었습니다.결과적으로 문자 집합 인식 함수 mysql_real_escape_string()이 사용 된 경우에도 SQL 삽입이 가능했습니다. 이 버그가 수정되었습니다.

해결 방법. mysql_real_escape_string() 구문 분석에서 버그 수정을 포함하지만 MySQL 5.0.1 이상을 실행하는 버전으로 MySQL을 업그레이드 할 수없는 경우 해결 방법으로 NO_BACKSLASH_ESCAPES SQL 모드를 사용할 수 있습니다. (이 모드는 MySQL 5.0.1에서 추가되었습니다.) NO_BACKSLASH_ESCAPES는 백 슬래시가 특수 문자로 간주되지 않는 SQL 표준 호환성 모드를 지원합니다. 결과는 쿼리가 실패하게됩니다.

SET GLOBAL sql_mode='NO_BACKSLASH_ESCAPES'; 

이 SQL 모드도 될 수 있습니다

SET sql_mode='NO_BACKSLASH_ESCAPES'; 

또한 모든 클라이언트에 대해 전 세계적으로 모드를 설정할 수 있습니다

입력, 현재 연결에 대해 다음 SQL 문을이 모드를 설정하려면 --sql-mode = NO_BACKSLASH_ESCAPES 명령 줄 옵션을 사용하거나 서버 옵션 파일 (예 : 시스템에 따라 my.cnf 또는 my.ini)에서 sql-mode = NO_BACKSLASH_ESCAPES를 설정하여 서버가 시작될 때 자동으로 활성화됩니다. . (Bug # 8378, CVE-2006-2753)

버그 # 8303도 참조하십시오.

+1

이 문제는 오래 전에 고쳐졌습니다. –

+1

'NO_BACKSLASH_ESCAPES' [다른 취약점들을 소개합니다] (http://stackoverflow.com/a/23277864/623041). – eggyal

+2

5.1.11에서 수정 됨 - 링크가 끊어졌습니다. 보관 파일은 다음과 같습니다. https://web.archive.org/web/20120501203047/http://dev.mysql.com:80/doc/refman/5.1/ ko/news-5-1-11.html – Bastion