Проблема с инъекцией MySQL - PullRequest
7 голосов
/ 16 июня 2011

В последнее время я кодировал свой веб-сайт на PHP, и я очень гордился своими хорошими практиками санации своего ввода, прежде чем я использовал его в запросе.Все шло отлично, пока мой друг не сказал, что мне нужно очистить мой вклад.Когда я попытался объяснить ему, что это было продезинфицировано, он показал мне, что нашел все в таблице «пользователей» в моей базе данных.Я не знал, как, поэтому я подумал, что опубликую то, что я делаю неправильно, из-за чего моя дезинфекция не работает.Вот код PHP, который он использовал:

start_mysql(); // Starts the databases stuff, etc.

$id = mysql_real_escape_string($_GET['id']);
$game = mysql_query("SELECT * FROM `games` WHERE `id` = $id LIMIT 0, 1");

Все, что он делал, это изменял параметр id, позволяя ему использовать SQL-инъекцию в моей базе данных.Я думал, что mysql_real_escape_string избежал всех символов, как это, но, очевидно, я был неправ.Я провел несколько тестов с нормальной строкой, чтобы увидеть, что произойдет, и вот что он сказал

URL: /game.php?id= 'OR' '='

echo($_GET['id']); // This echo'd: \' OR \'\' = \'
echo(mysql_real_escape_string($_GET['id'])); // This echo'd: \\\' OR \\\'\\\' = \\\'

Итак, мой простой вопрос: что я делаю не так?

Ответы [ 8 ]

6 голосов
/ 16 июня 2011

Вы должны поместить экранированную строку в одинарные кавычки:

WHERE `id` = '$id' 
4 голосов
/ 16 июня 2011

Поскольку id был целочисленным параметром, а вы не заключили его в одинарные кавычки в SQL, значение $id отправляется непосредственно в ваш запрос.Если вы ожидали целое число id, то вам следует убедиться, что значение $_GET['id'] является действительным целым числом.

$id = intval($_GET['id']);
3 голосов
/ 16 июня 2011

Матовый,

mysql_real_escape_string () будет фильтровать только по определенным символам, если вы действительно хотите предотвратить атаки с использованием инъекций, ознакомьтесь с этой другой статьей переполнения стека, в которой предлагается использовать подготовленные операторы:

Подготовленные заявления

PHP Ручной ввод для подготовленных операторов

Редактировать: Также ознакомьтесь с публикациями Слакса и Майкла о переносе вашей переменной в одинарные кавычки.

Удачи!

H

1 голос
/ 16 июня 2011

Cast ID.Если это строка, она будет приведена к 0. $ id = (int) $ _ GET ['id'];

Кроме того, MySQL поддерживает кавычки вокруг строки и чисел в запросе.

$game = mysql_query("SELECT * FROM `games` WHERE `id` = '$id' LIMIT 0, 1");
1 голос
/ 16 июня 2011

Вам необходимо использовать привязку параметра api . Проблема в этом куске кода:

WHERE `id` = $id

Вы напрямую интерполируете ввод пользователя в свой оператор SQL Это открытая дверь сарая для атак SQL-инъекций.

0 голосов
/ 01 июня 2012

Вы не можете предотвратить SQL-инъекции, используя mysql_real_escape_string(). Он используется для экранирования специальных символов, таких как одинарные кавычки ('), двойные кавычки (") и т. Д.

Для предотвращения SQL-инъекций вы должны использовать операторы PDO и функции фильтрации в PHP для очистки пользовательских данных.

0 голосов
/ 16 июня 2011

Весьма вероятно, что в вашей конфигурации есть magic_quote_gpc, древняя попытка в PHP сделать магически защищенные скрипты.У него было несколько недостатков, и с тех пор он устарел, и его планировалось полностью удалить в 5.4, когда я в последний раз слышал об этом.

Если у вас есть доступ к вашей конфигурации php.ini, вам следует отключить ее.В противном случае вы можете изменить свой сценарий, чтобы он учитывал его и очищал ваш ввод.

Все это задокументировано здесь: http://www.php.net/manual/en/security.magicquotes.disabling.php

В противном случае в mysqli_real_escape_string () нет ничего плохого.

0 голосов
/ 16 июня 2011

Вы не используете параметризованные запросы.

MDB2 позволяет это, хотя эта библиотека может перестать работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...