굴을 파는 것이 아닌 미래 세대를 위해 나무를 심는다는 생각으로 PHP, MYSQL 버전을 제공합니다. 앞으로는 "문제"가 더 이상 "문제"가 되지 않도록 정보를 제공합니다.
참고: 트릭은 MYSQL5.5.37-log에서 수정되었지만 여전히 주입 문제에 대한 확실한 해결책은 없습니다. 많은 회사의 시스템이 여전히 Mysql5.0을 사용하고 있으므로 즉시 개선할 것을 제안합니다. 이것이 바로 제가 "프로그래머들이 자신의 능력을 빠르게 향상시킬 수 있는 여러 가지 방법에 대해 이야기하는" 이유이기도 합니다. "에서 언급 된 매우 중요한 사항입니다.
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('servername','username','password'); mysql_select_db("test"); mysql_query("SET NAMES GBK"); $_POST['username'] = chr(0xbf).chr(0x27).' OR username = username /*'; $_POST['password'] = 'guess'; $username = addslashes($_POST['username']); $password = addslashes($_POST['password']); $sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'"; $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['username']); $password = mysql_real_escape_string($_POST['password']); $sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'"; $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['username']); $password = mysql_real_escape_string($_POST['password']); $sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'"; $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"
참고: 세 번째 mysql_real_escape_string이 주입을 방지할 수 있는 이유는 mysql_escape_string 자체가 현재 인코딩을 결정할 수 없기 때문입니다. 이를 추가하면 인코딩 주입을 방지할 수 있습니다. 문제. SQL 주입은 어느 정도 방지할 수 있지만, 여전히 다음과 같은 완벽한 솔루션을 권장합니다.
$pdo = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass'); $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 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.