PHP에서 SQL 삽입을 방지하기 위해 더 이상 addlashes 및 mysql_real_escape_string을 사용하지 마세요.

WBOY
풀어 주다: 2016-08-08 09:30:02
원래의
1074명이 탐색했습니다.

이 블로거는 다양한 인터넷 기술에 관심이 많으며 장황하고 강박 장애를 동반하는 경우가 많습니다. 기사가 도움이 된다고 생각하시면 저를 팔로우하세요. 재인쇄할 때 "Dark Blue Scythe"를 표시해 주십시오.


SQL 삽입을 방지하기 위해 여전히 addlashes 및 str_replace를 사용하는 많은 PHP 웹사이트를 보았습니다. 다음에서 확인해 보세요. Baidu." PHP anti-injection"도 이를 사용하고 있습니다. 실제로는 mysql_real_escape_string에도 해커가 이를 우회할 수 있는 방법이 있는 것으로 나타났습니다. 세 가지 방법 , 그렇다면 내 블로그 게시물은 모든 후발자들에게 이 구덩이를 우회하도록 상기시키는 데 의미가 있을 것입니다.

굴을 파는 것이 아닌 미래 세대를 위해 나무를 심는다는 생각으로 PHP, MYSQL 버전을 제공합니다. 앞으로는 "문제"가 더 이상 "문제"가 되지 않도록 정보를 제공합니다.

str_replace 및 다양한 PHP 문자 교체 기능을 사용하면 이런 "검은색"이 발생하는 것은 말할 필요도 없습니다. "목록" 방어는 시간의 시험을 견디지 못하는 것으로 입증되었습니다.

다음은 addlasher와 mysql_real_escape_string을 우회하는 방법이다( 트릭ck).


참고: 트릭은 MYSQL5.5.37-log에서 수정되었지만 여전히 주입 문제에 대한 확실한 해결책은 없습니다. 많은 회사의 시스템이 여전히 Mysql5.0을 사용하고 있으므로 즉시 개선할 것을 제안합니다. 이것이 바로 제가 "프로그래머들이 자신의 능력을 빠르게 향상시킬 수 있는 여러 가지 방법에 대해 이야기하는" 이유이기도 합니다. "에서 언급 된 매우 중요한 사항입니다.

참고: 귀하의 시스템이 SQL 주입 위험이 있는지 확실하지 않은 경우, 다음 DEMO를 서버에 배포하십시오. 실행 결과가 동일하다면 최종 완벽한 솔루션을 참조하십시오.

MYSQL:

mysql> select version();
+---------------------+
| version()           |
+---------------------+
| 5.0.45-community-ny |
+---------------------+
1 row in set (0.00 sec)
mysql> create database test default charset GBK;
Query OK, 1 row affected (0.00 sec)
mysql> use test;
Database changed
mysql> CREATE TABLE users (
    username VARCHAR(32) CHARACTER SET GBK,
    password VARCHAR(32) CHARACTER SET GBK,
    PRIMARY KEY (username)
);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into users SET username='ewrfg', password='wer44';
Query OK, 1 row affected (0.01 sec)
mysql> insert into users SET username='ewrfg2', password='wer443';
Query OK, 1 row affected (0.01 sec)
mysql> insert into users SET username='ewrfg4', password='wer4434';
Query OK, 1 row affected (0.01 sec)=
로그인 후 복사

PHP:

<?php
echo "PHP version: ".PHP_VERSION."\n";

mysql_connect(&#39;servername&#39;,&#39;username&#39;,&#39;password&#39;);
mysql_select_db("test");
mysql_query("SET NAMES GBK");

$_POST[&#39;username&#39;] = chr(0xbf).chr(0x27).&#39; OR username = username /*&#39;;
$_POST[&#39;password&#39;] = &#39;guess&#39;;

$username = addslashes($_POST[&#39;username&#39;]);
$password = addslashes($_POST[&#39;password&#39;]);
$sql = "SELECT * FROM  users WHERE  username = &#39;$username&#39; AND password = &#39;$password&#39;";
$result = mysql_query($sql) or trigger_error(mysql_error().$sql);

var_dump(mysql_num_rows($result));
var_dump(mysql_client_encoding());

$username = mysql_real_escape_string($_POST[&#39;username&#39;]);
$password = mysql_real_escape_string($_POST[&#39;password&#39;]);
$sql = "SELECT * FROM  users WHERE  username = &#39;$username&#39; AND password = &#39;$password&#39;";
$result = mysql_query($sql) or trigger_error(mysql_error().$sql);

var_dump(mysql_num_rows($result));
var_dump(mysql_client_encoding());

mysql_set_charset("GBK");
$username = mysql_real_escape_string($_POST[&#39;username&#39;]);
$password = mysql_real_escape_string($_POST[&#39;password&#39;]);
$sql = "SELECT * FROM  users WHERE  username = &#39;$username&#39; AND password = &#39;$password&#39;";
$result = mysql_query($sql) or trigger_error(mysql_error().$sql);

var_dump(mysql_num_rows($result));
var_dump(mysql_client_encoding());
로그인 후 복사

결과:
PHP version: 5.2.5
int(3)
string(6) "latin1"
int(3)
string(6) "latin1"
int(0)
string(3) "gbk" 
로그인 후 복사
할 수 있습니다. 보세요 addlashes를 사용하든 mysql_real_escape_string을 사용하든 코딩 취약점을 악용하여 비밀번호를 입력하여 서버에 로그인할 수 있는 주입 공격을 수행할 수 있습니다! ! ! ! (공격 원리에 대해서는 자세히 설명하지 않겠습니다. 관심 있는 학생들은 문자 인코딩의 단일 바이트 및 다중 바이트 문제를 공부할 수 있습니다.)

참고: 세 번째 mysql_real_escape_string이 주입을 방지할 수 있는 이유는 mysql_escape_string 자체가 현재 인코딩을 결정할 수 없기 때문입니다. 이를 추가하면 인코딩 주입을 방지할 수 있습니다. 문제. SQL 주입은 어느 정도 방지할 수 있지만, 여전히 다음과 같은 완벽한 솔루션을 권장합니다.

완벽한 해결책은 PDO 및 MYSQLi를 준비된 문 메커니즘과 함께 사용하여 mysql_query를 대체하는 것입니다(참고: mysql_query는 PHP 5.5.0부터 더 이상 사용되지 않으며 향후 이동될 예정입니다). 제외):

PDO:

$pdo = new PDO(&#39;mysql:dbname=dbtest;host=127.0.0.1;charset=utf8&#39;, &#39;user&#39;, &#39;pass&#39;);

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
$stmt->execute(array('name' => $name));

foreach ($stmt as $row) {
    // do something with $row
}
로그인 후 복사

MYSQLi:

$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
$stmt->bind_param('s', $name);

$stmt->execute();

$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    // do something with $row
}
로그인 후 복사

위 내용은 PHP에서 SQL 삽입을 방지하는 방법을 소개합니다. 더 이상 addlashes 및 mysql_real_escape_string을 사용하지 마세요. 관련 내용이 포함되어 있어 PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.

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