[php] DB에 연결하지 않고 mysql_real_escape_string의 대안

DB 연결없이 건식 테스트를 수행해야 할 때처럼 데이터베이스에 연결하지 않고 mysql_real_escape_string으로 작동하는 함수를 갖고 싶습니다. mysql_escape_string은 더 이상 사용되지 않으므로 바람직하지 않습니다. 내 결과 중 일부 :

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

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



답변

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

만하는 경우 테스트 , 당신은뿐만 아니라 사용할 수 mysql_escape_string()는 SQL 인젝션 공격에 대한 보증 100 % 아닙니다, 그러나 그것은 DB 연결없이 안전한 빌드 아무것도 불가능하다.


답변

음, 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);
}


답변

내 다른 대답과는 정반대 로이 다음 함수는 멀티 바이트 문자로도 안전합니다.

// 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;
}

나보다 더 많은 지식이있는 사람이 위의 코드가 작동하지 않는 이유를 말해 줄 수 있기를 바랍니다.


답변

추가 연구를 통해 다음을 발견했습니다.

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

보안 수정 :

다중 바이트 인코딩 처리에서 SQL 삽입 보안 구멍이 발견되었습니다. 버그는 서버에 있었으며 mysql_real_escape_string () C API 함수로 이스케이프 된 문자열을 잘못 구문 분석했습니다.

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

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

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

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

현재 연결에 대해이 모드를 설정하려면 다음 SQL 문을 입력하십시오.

SET sql_mode='NO_BACKSLASH_ESCAPES';

모든 클라이언트에 대해 전역 적으로 모드를 설정할 수도 있습니다.

SET GLOBAL sql_mode='NO_BACKSLASH_ESCAPES';

이 SQL 모드는 명령 줄 옵션 –sql-mode = NO_BACKSLASH_ESCAPES를 사용하거나 서버 옵션 파일 (예 : my.cnf 또는 my.ini)에서 sql-mode = NO_BACKSLASH_ESCAPES를 설정하여 서버가 시작될 때 자동으로 활성화 될 수도 있습니다. , 시스템에 따라 다름). (버그 # 8378, CVE-2006-2753)

Bug # 8303도 참조하십시오.


답변