PHP MySQLI Предотвращает внедрение SQL [дубликат]
На этот вопрос уже есть ответ здесь:
Я создал веб-сайт, который скоро будет запущен, и у меня просто есть пара вопросов о предотвращении внедрения SQL, я понимаю, как использовать mysqli_real_escape_string
, но мне просто интересно, нужно ли мне использовать это для всех переменных, которые я получаю для моего оператора SQL и должен ли я использовать его, когда я также выполняю инструкции select или просто при вставке, обновлении и удалении? Также, какую еще безопасность вы бы порекомендовали мне внедрить, прежде чем я запущу сайт в эксплуатацию, заранее спасибо за любую помощь!
2 answers
Любой запрос может быть введен, будь то чтение или запись, постоянный или временный. Инъекции могут быть выполнены путем завершения одного запроса и запуска отдельного (возможно с помощью mysqli
), что делает предполагаемый запрос неактуальным.
Любой ввод в запрос из внешнего источника, будь то от пользователей или даже от внутреннего, следует рассматривать как аргумент запроса и параметр в контексте запроса. Любой параметр в запросе должен быть параметризован. Это приводит к правильно параметризованный запрос, из которого можно создать подготовленную инструкцию и выполнить с аргументами. Например:
SELECT col1 FROM t1 WHERE col2 = ?
?
является заполнителем для параметра. Используя mysqli
, вы можете создать подготовленный оператор с помощью prepare
, привязать переменную (аргумент) к параметру с помощью bind_param
и выполнить запрос с помощью execute
. Вам вообще не нужно очищать аргумент (на самом деле это вредно). mysqli
делает это за вас. Полный процесс будет следующим:
$stmt = mysqli->prepare("SELECT col1 FROM t1 WHERE col2 = ?");
$stmt->bind_param("s", $col2_arg);
$stmt->execute();
Существует также важное различие между параметризованным запросом и подготовленным оператором. Это утверждение, хотя и подготовлено, не параметризовано и, следовательно, уязвимо для инъекций:
$stmt = mysqli->prepare("INSERT INTO t1 VALUES ($_POST[user_input])");
Подведем итог:
- Все Запросы должны быть правильно параметризованы (если только у них нет параметров)
- Все аргументы запроса должны рассматриваться как можно более враждебно, независимо от их источника
Он будет закрыт через несколько секунд, но просто для того, чтобы все было ясно
Я понимаю, как использовать строку mysqli_real_escape_string
Боюсь, что это не так.
Если мне придется использовать это для всех переменных, которые я получаю для своего оператора SQL
Определенно нет.
эта функция должна использоваться только для форматирования строк SQL
Должен ли я использовать его, когда я также выполняю инструкции select или просто при вставке обновления и удалить?
ЛЮБОЙ оператор SQL. Но опять же, не "используя mysqli_real_escape_string", а полностью и правильно форматируя ваши литералы
Также какие другие меры безопасности вы бы рекомендовали
Что касается безопасности SQL - вы должны правильно форматировать не только строки, но и литералы любого вида . И для каждого из них требуется отдельный набор правил форматирования