Я не уверен, как я могу сделать безопасные входы со строками.
Например, я получил:
$id = intval($_POST['id']); $name = $_POST['name']; $sql->query("UPDATE customers SET name = " . $sql->escape_string($name) . " WHERE id = {$id}");
Я уверен, что $name
недостаточно защищено. Как я могу защитить его, чтобы предотвратить уязвимость XSS?
С уважением, циклон.
Защита XSS должна выполняться на стороне вывода, а не на носителе данных (базе данных). База данных не знает, где будут отображаться данные. Если данные, которые нужно сохранить, являются текстовыми (как в этом случае с $name
), вы должны хранить его как текст, а не HTML.
Если вы действительно хотите избавиться от возможных HTML-тегов, используйте $name = strip_tags($_POST['name'])
, но правильный способ предотвратить XSS vulns – это ускользнуть от него на выходе с помощью htmlspecialchars
(или htmlentities
).
Если вы хотите использовать функции фильтра PHP, вот пример, который удаляет HTML-теги:
$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING);
Документы PHP:
XSS не имеет ничего общего с вашей базой данных, в основном.
Межсайтовый скриптинг (XSS) – это уязвимость компьютерной безопасности, обычно встречающаяся в веб-приложениях, которая позволяет злоумышленникам внедрять клиентский скрипт в веб-страницы, просматриваемые другими пользователями.
Может быть, вы ссылаетесь на SQL-инъекцию? Вы уже ускользали от ввода, вы можете дополнительно дезинфицировать его, применяя переменные к соответствующим типам.
Когда дело доходит до безопасности, я всегда думаю, что имеет смысл быть как можно более строгим, но не более строгим. Если вы можете определить, что имя недействительно, прежде чем вставлять его в базу данных, почему бы не отклонить его?
Кто-нибудь имеет имя с тегом HTML в нем? Возможно нет. Но как насчет апострофа или дефиса? Определенно.
Имея это в виду, давайте посмотрим, как будет выглядеть действительное имя:
Теперь, когда вы определили, как выглядит действительное имя, отклоните все имена, которые не соответствуют этим критериям:
/* If the input contains any character that is not a capital letter, a lowercase letter, whitespace, a hyphen, a period, or an apostrophe, then preg_match with return true. */ if (preg_match('/[^A-Za-z\s\-\.\']/', $_POST['Name'])) { // Invalid name } else { // Valid name }
Код, который вы предоставили, направлен на защиту повторных атак SQL Injection, а не XSS-атак, которые совершенно разные.
SQL Injection – это то, где злоумышленник использует код SQL для получения данных в вашей базе данных или из нее так, как вы этого не предполагали. Правильное избежание строки SQL, как вы делаете, смягчит это. (что, я не знаю из вашего кода, какой класс представляет собой объект $sql
, и, следовательно, я не могу сказать, является ли $sql->escape_string()
достаточной защитой, я предполагаю, что это так, но мне нужно будет знать больше об объекте, чтобы быть уверенным)
Атаки XSS («Межсайтовый скриптинг») – это то, где злоумышленнику удалось получить код HTML, CSS или Javascript на вашей странице, в результате чего последующие загрузки страниц отображаются с нежелательным контентом.
Это может быть достигнуто злоумышленником различными способами, но, как правило, вы должны следить за тем, чтобы любые данные, вводимые пользователями, которые будут отображаться на вашем сайте, должны быть отфильтрованы, чтобы предотвратить его использование HTML, CSS или JS-кода. Если это так, вы должны либо полностью удалить код, либо использовать экранирование HTML ( htmlentities()
PHP и т. htmlentities()
), Чтобы убедиться, что он отображается безопасным образом.
В настоящее время вы ничего не предпринимаете, чтобы предотвратить это в коде, который вы нам показали, но в равной степени от кода, который вы нам показали, мы не можем определить, должны ли эти данные защищаться от атак XSS. Это зависит от того, когда и как он используется.
Для очистки записей перед их помещением в sql я всегда делаю это:
trim($string) // Cuts off spacing and newlines in the beginning or end
А также
mysql_real_escape_string($string) // prevents SQL injections
Примечание. Любая часть строки запроса sql может быть mysql_real_escape_string'd. Вся строка не обязательно должна быть; до тех пор, пока какая-то часть сбежала, запрос будет безопасным от инъекции.