> 백엔드 개발 > PHP 튜토리얼 > PHP에서 SQL 주입을 방지하는 방법 (2)

PHP에서 SQL 주입을 방지하는 방법 (2)

WBOY
풀어 주다: 2016-07-29 09:15:00
원래의
946명이 탐색했습니다.

다음 예와 같이 사용자가 SQL 문에 직접 쿼리를 입력하는 경우 애플리케이션이 SQL 주입에 취약합니다.

<code><span>$unsafe_variable</span> = <span>$_POST</span>[<span>'user_input'</span>];
mysql_query(<span>"INSERT INTO table (column) VALUES ('"</span> . <span>$unsafe_variable</span> . <span>"')"</span>);</code>
로그인 후 복사

이는 사용자가 유사 VALUE를 입력할 수 있기 때문입니다. "); DROP TABLE 테이블; - 쿼리는 다음과 같습니다.

<code><span><span>INSERT</span><span>INTO</span><span>table</span> (<span>column</span>) <span>VALUES</span>(<span>'VALUE'</span>);</span><span><span>DROP</span><span>TABLE</span><span>table</span>;</span>'</code>
로그인 후 복사

이 상황을 어떻게 방지해야 할까요? Theo의 답변을 살펴보겠습니다
준비된 문과 매개변수화된 쿼리를 사용하세요. 매개변수가 포함된 SQL 문은 데이터베이스 서버로 전송되어 구문 분석됩니다! 공격자가 SQL을 악의적으로 주입하는 것은 불가능합니다!
이 목표를 달성하려면 기본적으로 두 가지 옵션이 있습니다.

1. PDO(PHP 데이터 개체) 사용

<code><span>$stmt</span> = <span>$pdo</span>->prepare(<span>'SELECT * FROM employees WHERE name = :name'</span>);
<span>$stmt</span>->execute(<span>array</span>(<span>':name'</span> => <span>$name</span>));
<span>foreach</span> (<span>$stmt</span><span>as</span><span>$row</span>) {
    <span>// do something with $row</span>
}</code>
로그인 후 복사

2. mysqli

<code><span>$stmt</span><span>=</span><span>$dbConnection</span><span>-></span>prepare(<span>'SELECT * FROM employees WHERE name = ?'</span>);
<span>$stmt</span><span>-></span>bind_param(<span>'s'</span>, <span>$name</span>);
<span>$stmt</span><span>-></span>execute();
<span>$result</span><span>=</span><span>$stmt</span><span>-></span>get_result();
<span>while</span> (<span>$row</span><span>=</span><span>$result</span><span>-></span>fetch_assoc()) {
    <span>// do something with $row</span>
}</code>
로그인 후 복사

PDO(PHP) 사용 데이터 객체 )
PDO를 사용하여 MySQL 데이터베이스에 액세스할 때 실제 준비된 명령문은 기본적으로 사용되지 않습니다. 이 문제를 해결하려면 준비된 문의 에뮬레이션을 비활성화해야 합니다. PDO를 사용하여 연결을 생성하는 예는 다음과 같습니다.

<code><span>$dbConnection</span><span>=</span><span>new</span> PDO(<span>'mysql:dbname=dbtest;host=127.0.0.1;charset=utf8'</span>, <span>'user'</span>, <span>'pass'</span>);
<span>$dbConnection</span><span>-></span>setAttribute(PDO<span>::ATTR_EMULATE_PREPARES</span>, <span>false</span>);
<span>$dbConnection</span><span>-></span>setAttribute(PDO<span>::ATTR_ERRMODE</span>, PDO<span>::ERRMODE_<strong>Exception</strong></span>);</code>
로그인 후 복사

위의 예에서 오류 모드 ERRMODE는 반드시 필요한 것은 아니지만 추가하는 것이 좋습니다. 이 방법은 치명적인 오류가 발생할 때 스크립트를 중지하지 않습니다. 그리고 개발자에게 오류를 잡을 수 있는 기회를 제공하십시오(PDOException 예외가 발생하는 경우).
setAttribute() 행은 필수입니다. 이는 PDO에게 에뮬레이트된 준비된 문을 비활성화하고 실제 준비된 문을 사용하도록 지시합니다. 이렇게 하면 명령문과 값이 MySQL 데이터베이스 서버로 전송되기 전에 PHP에서 구문 분석되지 않습니다(공격자는 악성 SQL을 삽입할 기회가 없습니다).
물론 생성자 옵션에서 문자 세트 매개변수를 설정할 수 있습니다. 특히 '이전' PHP 버전(5.3.6)은 DSN의 문자 세트 매개변수를 무시합니다.

설명
전달한 SQL 준비 문이 데이터베이스 서버에 의해 구문 분석되고 컴파일되면 어떻게 되나요? 위의 예에서 a? 또는 :name과 같은 문자를 지정하여 필터링할 내용을 데이터베이스 엔진에 알립니다. 그런 다음 실행을 호출하여 지정한 매개변수 값과 결합된 준비된 문을 실행합니다. 여기서 가장 중요한 점은 매개 변수 값이 SQL 문자열이 아닌 미리 컴파일된 명령문과 결합된다는 점입니다. SQL 주입은 악성 문자열이 포함된 SQL 스크립트를 기만적으로 생성하여 데이터베이스로 보내는 방식으로 작동합니다. 별도의 SQL 매개변수를 사용하면 위험이 줄어듭니다. 준비된 문을 사용할 때 보내는 모든 매개변수는 문자열로만 처리됩니다(단, 데이터베이스 엔진은 일부 매개변수 최적화를 수행할 수 있으며 이는 물론 위의 경우 숫자가 될 수 있음). 예를 들어 $name 변수에 'sarah';DELETE * FROM 직원이 포함된 경우 결과는 검색 문자열 "'sarah';DELETE * FROM 직원"만 되며 빈 테이블을 얻지 못합니다.
준비된 문을 사용하는 또 다른 이점은 동일한 세션에서 동일한 문을 여러 번 실행하는 경우 한 번만 구문 분석되고 컴파일되므로 속도가 약간 향상된다는 것입니다.
아, 그리고 삽입하는 방법을 물어보셨기 때문에 다음은 예(PDO 사용)입니다.

<code><span>$preparedStatement</span><span>=</span><span>$db</span><span>-></span>prepare(<span>'INSERT INTO table (column) VALUES (:column)'</span>);
<span>$preparedStatement</span><span>-></span>execute(<span>array</span>(<span>':column'</span><span>=></span><span>$unsafeValue</span>));</code>
로그인 후 복사
http://www.jb51.net/article/36042.htm

위 내용은 PHP에서 SQL 인젝션을 방지하는 방법(2)을 관련 내용까지 포함하여 소개한 내용으로, PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿