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

12
задан Peter Mortensen 15 July 2019 в 13:54
поделиться

4 ответа

Я думаю, что вы путаете две проблемы безопасности: инъекция SQL и межсайтовый скриптинг (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, но «постсообщение» может разрешать BBcode, Markdown или подмножество HTML. Если вы экранировали все входные данные, чтобы предотвратить XSS, вам нужно будет отменить экранирование значений из базы данных, например, htmlspecialchars_decode .

Одна из проблем заключается в том, что отмена экранирования экранированной строки не всегда возвращает исходную строку (unescape(escape($orig)) не обязательно совпадает с $orig). Даже с htmlspecialchars и htmlspecialchars_decode использование другого стиля кавычек вызовет эту проблему. Другой пример: если используется strip_tags, информация удаляется безвозвратно; вы не сможете отменить strip_tags. Таким образом, многие разработчики предпочитают использовать mysql_real_escape_string только для сохранения значений в базе данных и htmlspecialchars (или что-то еще) для подготовки строки из базы данных для использования в HTML.

10
ответ дан 2 December 2019 в 04:32
поделиться

mysql_real_escape_string() — единственный метод, который вам здесь понадобится.

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

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


Ресурсы:

По той же теме:

21
ответ дан 2 December 2019 в 04:32
поделиться

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

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

$_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 для ваших переменных не означает автоматически, что они безопасны в любом случае.

Другим подходом может быть использование подготовленных операторов.

1
ответ дан 2 December 2019 в 04:32
поделиться

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

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

1
ответ дан 2 December 2019 в 04:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: