2010-08-14 2 views
5

PHP :SQL 인젝션 -이 (oneliner)가 안전합니까?

 
$SQL = "SELECT goodies FROM stash WHERE secret='" . 
    str_replace("'",'',$_POST['secret']) . 
"'"; 

이 사악한 천재 해커가 내 SELECT에 SQL을 주입 할 수 - 어떻게?

+4

닫는'''을 이스케이프 처리하는 값의 끝에'\'가 포함되어있는 경우에도 여전히 잘못된 명령문을 얻을 수 있습니다. – Gumbo

+3

+1 : 흥미로운 질문입니다. 그러나 그것이 안전한지 아닌지에 관계없이, 나는 아직도 그것을 추천하지 않을 것이다. :) –

+0

정직한 사용자에게 영향을 미치지 않는 한 오류는 정상입니다. – T4NK3R

답변

6

나는 잠시 동안 이것에 대해 생각을 했어 내가이 문으로 SQL을 주입 할 수있는 방법을 볼 수 없습니다.

작은 따옴표로 시작하는 SQL 문자열은 백 슬래시 또는 다른 따옴표 (\' 또는 '')로 이스케이프하지 않는 한 다음 작은 따옴표에서 종료됩니다. 모든 작은 따옴표를 제거하기 때문에 두 배로 된 따옴표를 사용할 수 없습니다. 닫는 인용문에서 벗어나면 오류는 발생하지만 SQL 삽입은 발생하지 않습니다. 입력에서

  • 작은 따옴표는 무시됩니다

    그러나이 방법은 단점을 가지고 있습니다.

  • 입력의 백 슬래시가 올바르게 처리되지 않습니다. 이스케이프 코드로 처리됩니다.
  • 마지막 문자가 백 슬래시 인 경우 오류가 발생합니다.
  • 두 번째 매개 변수를 추가하기 위해 쿼리를 나중에 확장하면 이되어 SQL 주입 공격을 허용합니다. 초래 매개 변수 \OR 1 = 1 -- 호출

    $SQL = "SELECT goodies FROM stash WHERE secret='" . 
        str_replace("'",'',$_POST['secret']) . 
    "' AND secret2 = '" . 
        str_replace("'",'',$_POST['secret2']) . 
    "'"; 
    

    :

    SELECT goodies FROM stash WHERE secret='...' OR 1 = 1 
    

    :

    SELECT goodies FROM stash WHERE secret='\' AND secret2=' OR 1 = 1 -- ' 
    

    MySQL은이 같은으로 볼 것입니다 예를 들어

그것이 불가능하더라도 이 경우에 주입을 일으킬 수있는 단점은 이것을 SQL 삽입을 피하기위한 일반적인 목적에 부적합하게 만든다.

이미 지적했듯이 해결책은 준비된 진술을 사용하는 것입니다. 이것은 SQL 주입 공격을 막는 가장 확실한 방법입니다.

+0

나는 그것을한다. (많이!).하지만 str_replace를 mysql_real_escape_string ($ _ POST [ 'secret'])로 바꾸면 치료할 수있다. 그리고 에러를 일으킬 가능성이 있습니까?) – T4NK3R

+0

@ T4NK3R : 무엇을 많이합니까? mysql_real_escape_string이 제대로 작동하지 않는 매우 드문 경우가 있습니다 : http://ilia.ws/archives/103-mysql_real_escape_string-versus-Prepared- Statements.html 준비된 statem ents가 가장 좋은 방법이지만, mysql_real_escape_string이 올바르게 수행되면 작동해야합니다. –

+0

Do : 키 = 값 쌍을 추가합니다 (대부분 단순한 (int) 형 변환으로 "강화"되지만). BTW : 내 PHP 소스는 UTF-8이고 dbConnection도 있습니다 (mysql_set_charset ('utf8', $ dbCon);) - 지금 귀하의 링크를 읽으세요! – T4NK3R

14

mysql_real_escape_string() 또는 더 잘 준비된 명령문을 사용하지 않는 이유는 무엇입니까? 당신의 솔루션은 어리석은 것처럼 보입니다.

+9

+1을 준비하십시오. –

+0

seconded ... 특히 준비된 문 – prodigitalson

+0

가능한 한 "희박한"상태로 유지하려고합니다. – T4NK3R

-1

mysql_escape_string을 사용하지 않는 이유는 무엇입니까? 그리고 예, 그는 ' 대신 "을 추가하고 더하기,이 쿼리는 오류를 줄 것입니다.

+0

정직한 사용자에게 영향을 미치지 않는 한 오류는 정상입니다. – T4NK3R

+0

나는 쿼리'SELECT goodies FROM stash WHERE secret = ' "''이 문제가 없다고 생각할 것입니다. 큰 따옴표는 문자열을 끝내지 않을 것입니다. 어떤 종류의 오류를 언급하고 있습니까? –

0

일 수 있습니다. 가장 좋은 방법은 다음과 같습니다

$query = sprintf("SELECT goodies FROM stash WHERE secret='%s'", 
addcslashes(mysql_real_escape_string($_POST['secret']),'%_')); 
+0

필요하지 않습니다. – Gumbo

+0

예, addcslashes 함수는 선택 사항입니다. – barroco

+0

동적으로 명령문을 작성하므로 (옵션이 많은 검색의 경우) 오히려 유지하려고합니다. 각각의 키 - 값 쌍을 합쳐 하나의 문자열로 구문을 만들어서 간다. – T4NK3R

관련 문제