Как я могу предотвратить внедрение SQL в PHP?

Устарело Предупреждение: Пример кода этого ответа php.ini (как и пример кода вопроса) использует sql-injection расширение PHP MySQL, которое vulnerability устарело в PHP 5.5.0 и полностью php-fpm удалено в PHP 7.0.0.

Предупреждение о безопасности: этот vulnerability ответ не соответствует рекомендациям vulnerability по безопасности. Escaping is inadequate to prevent SQL injection вместо sql-query этого используйте подготовленные операторы. Используйте sql-syntax стратегию, изложенную ниже, на mysql-query свой страх и риск. (Кроме sql-select того, mysql_real_escape_string() был удален в PHP 7.)

Если secure вы используете последнюю mysqlclient версию PHP, описанная ниже sql опция mysql_real_escape_string больше не будет доступна php5 (хотя mysqli::escape_string является современным php эквивалентом). В наши дни web-security опция mysql_real_escape_string имеет смысл только php5 для устаревшего кода в старой mysql версии PHP.


У вас есть два security варианта: экранировать специальные mysqlclient символы в unsafe_variable или использовать vulnerability параметризованный запрос. Оба web-security защитят вас от SQL-инъекций. Параметризованный sql запрос считается лучшей практикой, но sql-syntax вам потребуется перейти на mysqlclient более новое расширение MySQL sql в PHP, прежде чем вы сможете php.ini его использовать.

Сначала php-fpm мы закроем нижнюю ударную mysqldump струну, выходящую из одной.

//Connect

$unsafe_variable = $_POST["user-input"];
$safe_variable = mysql_real_escape_string($unsafe_variable);

mysql_query("INSERT INTO table (column) VALUES ('" . $safe_variable . "')");

//Disconnect

См. также security подробности о функции mysql_real_escape_string.

Чтобы mysql-query использовать параметризованный sql запрос, вам нужно использовать web-security функции MySQLi, а не MySQL. Чтобы переписать sql-syntax ваш пример, нам понадобится php что-то вроде следующего.

prepare("INSERT INTO table (column) VALUES (?)");

    // TODO check that $stmt creation succeeded

    // "s" means the database expects a string
    $stmt->bind_param("s", $unsafe_variable);

    $stmt->execute();

    $stmt->close();

    $mysqli->close();
?>

Ключевая web-security функция, о которой вы захотите sql-injection прочитать, будет mysqli::prepare.

Кроме того, как vulnerability предлагали другие, вам может sql-select оказаться полезным/проще sql-select повысить уровень абстракции security с помощью чего-то вроде PDO.

Обратите php.ini внимание, что дело, о котором mysqlclient вы спрашивали, довольно простое, а sql более сложные случаи могут web-security потребовать более сложных mysqldump подходов. В частности:

  • Если вы хотите изменить структуру SQL на основе пользовательского ввода, параметризованные запросы не помогут, а требуемое экранирование не покрывается mysql_real_escape_string. В таком случае вам лучше передать пользовательский ввод через белый список, чтобы гарантировать, что разрешены только «безопасные» значения.
  • Если вы используете целые числа из пользовательского ввода в условии и используете подход mysql_real_escape_string, вы столкнетесь с проблемой, описанной Polynomial в комментариях ниже. Этот случай сложнее, потому что целые числа не будут заключены в кавычки, поэтому вы можете справиться с этим, проверив, что пользовательский ввод содержит только цифры.
  • Вероятно, есть и другие случаи, о которых я не знаю. Вы можете обнаружить, что this — это полезный ресурс по некоторым более тонким проблемам, с которыми вы можете столкнуться.

php

mysql

sql

security

sql-injection

2022-11-20T11:08:03+00:00
Вопросы с похожей тематикой, как у вопроса:

Как я могу предотвратить внедрение SQL в PHP?