Лучший способ защиты от внедрения MySQL и межсайтового скриптинга
На данный момент я применяю метод "брось все в стену и посмотри, что стоит", чтобы остановить вышеупомянутые проблемы. Ниже приведена функция, которую я собрал вместе:
function madSafety($string)
{
$string = mysql_real_escape_string($string);
$string = stripslashes($string);
$string = strip_tags($string);
return $string;
}
Тем не менее, я убежден, что есть лучший способ сделать это. Я использую FILTER_ SANITIZE_STRING, и это не похоже на полную безопасность.
Наверное, я спрашиваю, какие методы вы, ребята, используете и насколько они успешны? Спасибо
4 ответа
Просто делать много вещей, которые вы на самом деле не понимаете, не поможет вам. Вы должны понимать, что такое инъекционные атаки, и как именно и где и что делать.
В пунктах пули:
- Отключить магические кавычки. Это неадекватное решение, и они путают вещи.
- Никогда не вставляйте строки непосредственно в SQL. Используйте связанные параметры или экранируйте (используя
mysql_real_escape_string
). - Не убегайте (например,
stripslashes
) при извлечении данных из базы данных. - Когда вы встраиваете строки в HTML (например, когда вы
echo
), по умолчанию вы должны экранировать строку (используяhtmlentities
сENT_QUOTES
). - Если вам нужно встраивать html-строки в html, вы должны рассмотреть источник строки. Если это не заслуживает доверия, вы должны пропустить через фильтр.
strip_tags
в теории то, что вы должны использовать, но это недостатки; Вместо этого используйте HtmlPurifier.
Смотрите также: Каков наилучший метод для дезинфекции ввода пользователя с помощью PHP?
Лучший способ против внедрения SQL - это связывать переменные, а не "вставлять" их в строку. http://www.php.net/manual/en/mysqli-stmt.bind-param.php
Не надо! С помощью mysql_real_escape_string
достаточно, чтобы защитить вас от внедрения SQL и stropslashes
вы делаете после того, как делает вас уязвимым для SQL-инъекций. Если вы действительно этого хотите, поместите его как показано ниже:
function madSafety($string)
{
$string = stripslashes($string);
$string = strip_tags($string);
$string = mysql_real_escape_string($string);
return $string;
}
stripslashes
не очень полезно, если вы делаете mysql_real_escape_string
,
strip_tags
защищает от внедрения HTML/XML, а не SQL.
Важно отметить, что вы должны избегать своих строк по- разному, в зависимости от того, какое непосредственное использование вы используете для этого.
Когда вы делаете запросы MYSQL, используйте mysql_real_escape_string
, Когда вы выводите веб-страницы, используйте htmlentities
, Для создания веб-ссылок используйте urlencode
...
Как заметил vartec, если вы можете использовать заполнители любыми способами, сделайте это.
Эта тема так неправильно!
Вы не должны фильтровать ввод пользователя! Это информация, которую он ввел. Что вы собираетесь делать, если я хочу, чтобы мой пароль был таким: '"'>s3cr3t<script>alert()</script>
Отфильтруйте персонажей и оставьте меня с измененным паролем, чтобы я даже не смог сделать свой первый вход в систему? Это плохо.
Правильное решение - использовать подготовленные заявления или mysql_real_escape_string()
чтобы избежать SQL-инъекций и использовать контекстно-зависимое экранирование символов, чтобы избежать путаницы в вашем HTML-коде.
Напомню, что Интернет - это только один из способов представления информации, введенной пользователем. Вы бы согласились на такую зачистку, если бы какое-то программное обеспечение для настольных компьютеров делало это? Я надеюсь, что ваш ответ НЕТ, и вы поймете, почему это не правильный путь.
Обратите внимание, что в другом контексте разные символы должны быть экранированы. Например, если вам нужно отобразить имя пользователя в виде всплывающей подсказки, вы будете использовать что-то вроде:
<span title="{$user->firstName}">{$user->firstName}</span>
Однако, если пользователь установил свое имя как '"><script>window.document.location.href="http://google.com"</script>
Что ты собираешься сделать? Убрать цитаты? Это было бы так неправильно! Вместо того чтобы делать это бессмысленно, рассмотрите возможность экранирования кавычек при отображении данных, а не при их сохранении!
Другой контекст, который вы должны учитывать, - это отображение самого значения. Рассмотрим ранее использованный HTML-код и представьте, что имя пользователя будет похоже <textarea>
, Это обернуло бы весь HTML-код, который следует за этим элементом textarea, таким образом разбивая всю страницу.
Еще раз - рассмотрите возможность экранирования данных в зависимости от контекста, в котором вы их используете!
PS Не совсем уверен, как реагировать на эти отрицательные голоса. Вы, люди, действительно читаете мой ответ?