Я в безопасности от инъекции MySQL?

Это достаточно хорошо, чтобы избежать инъекции SQL?

mysql_real_escape_string(htmlentities (urlencode($_POST['postmessage'])));

Ответ 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.

Ответ 2

mysql_real_escape_string() - единственный метод, который вам нужен здесь.

Вы не должны делать htmlentities() или urlencode() перед вставкой данных в вашу базу данных. Эти методы обычно представляют собой код, выполняемый во время рендеринга представления, которое вы предлагаете своим пользователям.

Лучший способ избежать внедрения SQL-кода - это использование подготовленных операторов.


Ресурсы:

На ту же тему:

Ответ 3

Вы также должны убедиться, что используете " вокруг места, где вы вставляете свой код.

Например, если вы делаете

$_POST['userid'] = mysql_real_escape_string($_POST['userid']);
mysql_query('SELECT * FROM user WHERE userid = '. $_POST['userid']);

mysql_real_escape_string ничего не поможет. Это потому, что $ _POST ['userid'] не окружен '.

Так что вы должны сделать

$_POST['userid'] = mysql_real_escape_string($_POST['userid']);
mysql_query('SELET * FROM user WHERE userid = \''. $_POST['userid'] .'\'');

вместо.

Таким образом, использование mysql_real_escape_string для ваших переменных не означает автоматически, что они безопасны в любом запросе.

Другой подход заключается в использовании подготовленных заявлений.

Ответ 4

Да, но есть причина не использовать mysql_real_escape_string(). Во-первых, это боль типа. Во-вторых, вы должны помнить, чтобы использовать его каждый раз. В-третьих, это делает ваш код уродливым. В-четвертых, вы должны помнить, чтобы процитировать ваши строки. В-пятых, сложнее вставить капли в db таким образом.

Обучение PDO улучшит вашу жизнь в долгосрочной перспективе. Труднее учиться, чем просто использовать mysql_real_escape_string(), но долгосрочные выгоды перевешивают неудобства кривой обучения.