Ответ 1
Я думаю, что вы путаете две проблемы безопасности: SQL injection и межсайтовый скриптинг (XSS).
Веб-сайт уязвим для SQL-инъекций, когда неправильно обработанный пользовательский ввод используется в SQL-запросе, который отправляется в базу данных SQL. Этот код, например, вводит уязвимость SQL-инъекции:
mysql_query("INSERT INTO postmessages (postmessage) VALUES ('" . $_POST['postmessage'] . "')");
Эту проблему легко устранить, если вы отменили ввод пользователя с помощью функции типа mysql_real_escape_string
:
mysql_query("INSERT INTO postmessages (postmessage) VALUES ('" . mysql_real_escape_string($_POST['postmessage']) . "')");
Это все, что вам нужно сделать, но сложная часть запоминает это для каждой части пользовательского ввода, которая используется в инструкции SQL.
Веб-сайт уязвим для межсайтового скриптинга, когда пользовательский ввод используется в HTML, который отправляется клиенту. Этот код, например, представляет уязвимость XSS:
echo "<div class='postmessage'>" . $_POST['postmessage'] . "</div>";
Уязвимость XSS устранена путем экранирования пользовательского ввода с помощью функции htmlspecialchars
:
echo "<div class='postmessage'>" . htmlspecialchars($_POST['postmessage']) . "</div>";
Опять же, это легко сделать, но легко забыть.
Обычно пользовательский ввод, который помещается в базу данных, которая будет использоваться при отправке HTML-кода позднее, сохраняется без изменений. То есть используется только mysql_real_escape_string
. Тем не менее, вы можете избежать ввода пользователем для предотвращения XSS, а затем выйти из XSS-безопасной строки, чтобы предотвратить SQL-инъекцию:
mysql_query("INSERT INTO postmessages (postmessage) VALUES ('" . mysql_real_escape_string(htmlspecialchars($_POST['postmessage'])) . "')");
Преимущество в том, что вам не нужно помнить о том, чтобы избегать значений из базы данных с помощью htmlspecialchars
, прежде чем записывать их в HTML. Недостатком является то, что некоторые значения могут быть экранированы с различными функциями. Например, имя пользователя, вероятно, будет экранировано с помощью htmlspecialchars
, но "postmessage" может разрешить BBcode, Markdown или подмножество HTML. Если вы избегаете всех входных данных, чтобы предотвратить XSS, тогда вам нужно будет unescape-значения из базы данных, например, htmlspecialchars_decode
.
Одна проблема заключается в том, что unescaping escape-строка не всегда возвращает исходную строку (unescape(escape($orig))
не обязательно совпадает с $orig
). Даже при использовании htmlspecialchars
и htmlspecialchars_decode
при использовании другого стиля кавычек это вызовет эту проблему. Другим примером является то, что если используется strip_tags
, информация удаляется безвозвратно; вы не сможете отменить strip_tags
. Таким образом, многие разработчики предпочитают использовать mysql_real_escape_string
только для сохранения значений в базе данных и htmlspecialchars
(или любого другого) для подготовки строки из базы данных, которая будет использоваться в HTML.