#php #mysql #security #sql-injection
#php #mysql #Безопасность #sql-инъекция
Вопрос:
Меня попросили решить проблему безопасности для сайта, который был настроен другим программистом. На данный момент я еще не видел ни одного кода, поэтому на данном этапе я отхожу от предположений и хочу изложить свои основы. Группа, размещающая сайт, провела проверку безопасности и обнаружила, что у них есть код, уязвимый для SQL-инъекции.
Пример: www.example.com/code.php?pid=2amp;ID=35 (ПОЛУЧИТЬ идентификатор параметра уязвимо для SQL-инъекции)
Теперь, поскольку я новичок, я объяснил, что, скорее всего, смогу решить проблему с хостом, но их сайт все равно должен быть просмотрен кем-то, кто обладает более глубокими знаниями в области безопасности.
Итак, чтобы позаботиться о потенциальных SQL-инъекциях (и не видя кода), я бы использовал mysql_real_escape_string:
$query = sprintf("SELECT * FROM table WHERE pid='%s' AND ID='%s'",
mysql_real_escape_string($pid),
mysql_real_escape_string($id));
Кроме того, я бы рассмотрел mysqli_real_escape_string и подготовленные инструкции, но я не знаю, как они настроены. Но будет ли mysql_real_escape_string заботиться о потенциальной SQL-инъекции?
Комментарии:
1. Вам было бы лучше использовать подготовленные инструкции.
Ответ №1:
По возможности пропустите старые mysql_*
материалы и используйте PDO.
$pdo = new PDO('mysql:host=localhost;dbname=whatever', $username, $password);
$statement = $pdo->prepare('SELECT * FROM table WHERE pid=:pid AND ID=:id');
$statement->bindParam(':pid', $_GET['pid']);
$statement->bindParam(':id', $_GET['id']);
$results = $statement->execute();
var_dump($results->fetchAll());
Ответ №2:
Эта функция должна работать нормально — ваши переменные заключены в одинарные кавычки в инструкции SQL, и любые одинарные или двойные кавычки будут экранированы.
Это означает, что ни одна из переменных не может «вырваться» из инструкции.
Ответ №3:
Да, mysql_real_escape_string() экранирует любые потенциально опасные символы. Если вы знаете, что аргументы являются числовыми, не помешало бы проверить это также с помощью is_numeric()
Вам также следует взглянуть на mysql::prepare — Это гарантирует, что выполняется только 1 оператор, и предотвратит дополнительные уязвимости SQL.
Ответ №4:
Если ID и PID являются целочисленными полями, почему бы не преобразовать их в int.
Таким образом, у вас обязательно будет номер, без SQL-инъекции :
$pid = (int) $pid;
$id = (int) $id;
Ответ №5:
Это должно быть нормально, но я бы всегда рекомендовал использовать подготовленные инструкции.