Лучший способ защиты от внедрения mysql и межсайтового скриптинга

На данный момент я применяю метод «брось все в стену и посмотрю, что мешает», чтобы решить вышеупомянутые проблемы. Ниже представлена ​​функция, которую я сколотил:

function madSafety($string)
{

$string = mysql_real_escape_string($string);
$string = stripslashes($string);
$string = strip_tags($string);
return $string;

}

Однако я убежден, что есть способ лучше. Я использую FILTER_ SANITIZE_STRING, и это не совсем безопасно.

Думаю, я спрашиваю, какие методы вы, ребята, используете и насколько они успешны? Спасибо


person Drew    schedule 20.02.2009    source источник
comment
dupe: stackoverflow.com/questions/129677/   -  person troelskn    schedule 20.02.2009
comment
Такой подход ошибочен по многим аспектам! Я опубликовал ответ ниже и оценил каждый из ответов -1, поскольку их авторы отказываются думать.   -  person Nikola Petkanski    schedule 01.11.2013


Ответы (4)


Если вы просто делаете много вещей, которых вы не понимаете, это вам не поможет. Вы должны понимать, что такое инъекционные атаки и как именно и где что делать.

В маркированном списке:

  • Отключить волшебные цитаты. Это неадекватное решение, и они запутывают дела.
  • Никогда не вставляйте строки непосредственно в SQL. Используйте связанные параметры или экранирование (используя mysql_real_escape_string).
  • Не отменяйте экранирование (например, stripslashes) при извлечении данных из базы данных.
  • Когда вы встраиваете строки в html (например, когда вы echo), вы должны по умолчанию экранировать строку (используя htmlentities с ENT_QUOTES).
  • Если вам нужно встроить html-строки в html, вы должны учитывать источник строки. Если он ненадежный, вы должны пропустить его через фильтр. strip_tags теоретически то, что вам следует использовать, но он ошибочен; Вместо этого используйте HtmlPurifier.

См. Также: Какой лучший метод очистки пользовательского ввода с помощью PHP?

person troelskn    schedule 20.02.2009
comment
Отлично - это значительно лучше, чем ответ, который я писал, но сейчас заброшен. +1 - person Dominic Rodger; 20.02.2009

Лучший способ противодействия SQL-инъекции - привязать переменные, а не «вставлять» их в строку. http://www.php.net/manual/en/mysqli-stmt.bind-param.php

person vartec    schedule 20.02.2009
comment
Будьте осторожны с допустимыми тегами - в любой тег можно встроить JS. - person Dominic Rodger; 20.02.2009
comment
Также - см. isisblogs. poly.edu/2008/08/16/ - person Dominic Rodger; 20.02.2009
comment
strip_tags ошибочен .. escape-строки, или, если вам действительно нужно разрешить HTML, используйте htmlpurifier - person troelskn; 20.02.2009

Не! Использование 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, если вы можете использовать заполнители, обязательно сделайте это.

person kmkaplan    schedule 20.02.2009
comment
Собственно, mysql_real_escape_string тоже не совсем безопасен. См. ilia.ws/archives/. - person Michael Borgwardt; 25.02.2009

Это такая неправильная тема!

Вы НЕ должны фильтровать ввод пользователя! Это информация, которую он ввел. Что вы собираетесь делать, если я хочу, чтобы мой пароль был таким: '"'>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, разбив, таким образом, всю страницу.

Еще раз - рассмотрите возможность экранирования данных в зависимости от контекста, в котором вы их используете!

P.S Не совсем уверен, как реагировать на эти отрицательные голоса. Вы действительно читаете мой ответ?

person Nikola Petkanski    schedule 01.11.2013
comment
Вместо того, чтобы удалять мой комментарий, постарайтесь понять, о чем я говорю. Если бы у пользователя было имя пользователя с такими тегами, я бы не удалял теги, я бы полностью отклонил имя пользователя и заставил их придумать имя пользователя, которое меньше, простите меня, глупо. Конечно, пароли будут другими, но имена пользователей с <script> в них? Отвергни это. - person Muhammad Abdul-Rahim; 10.07.2015
comment
Я не удалял ваш комментарий. Я отметил это, и кто-то решил, что флаг подходит. Что вводит пользователь, меня не касается, я забочусь о том, чтобы мое приложение работало правильно. Разобраться в данных и избежать их - две радикально разные вещи. Пожалуйста, не путайте их. Вы можете использовать все, что хотите, в качестве имени пользователя, ни уровень представления (html), ни уровень сохраняемости (mysql, postgre и т. Д.) Не должны стоять на вашем пути. Опять же, вопрос в том, как избежать данных, а не в том, как отфильтровать или применить к ним цензуру. - person Nikola Petkanski; 10.07.2015