Как мне защитить от межсайтовых скриптов? - PullRequest
4 голосов
/ 07 мая 2010

Я использую php, mysql с smarty, и я использую места, где пользователи могут оставлять комментарии и т. Д. Я уже экранировал символы перед тем, как вставить их в базу данных для SQL Injection. Что еще мне нужно сделать?

Ответы [ 5 ]

10 голосов
/ 07 мая 2010

XSS - это в основном HTML-экранирование (*).Каждый раз, когда вы берете строку простого текста и помещаете ее на страницу HTML, независимо от того, является ли этот текст из базы данных, непосредственно из пользовательского ввода, из файла или откуда-то еще полностью, вы должны избегать его.

Минимальный выход HTML - преобразовать все символы & в &amp; и все символы < в &lt;.Когда вы помещаете что-либо в значение атрибута, вам также необходимо экранировать символ кавычки, используемый для разделения атрибута, обычно от " до &quot;.Не вредно всегда избегать обеих кавычек (&quot; и апостроф одинарной кавычки &#39;), а некоторые люди также экранируют > до &gt;, хотя это необходимо только для одного углового случая в XHTML.

Любой хороший веб-ориентированный язык должен предоставить вам такую ​​функцию.Например, в PHP это htmlspecialchars():

<p> Hello, <?php htmlspecialchars($name); ?>! </p>

, а в шаблонах Smarty это модификатор escape:

<p> Hello, {$name|escape:'html'}! </p>

на самом деле, так как экранирование HTML - это то, что вам нужно 95% отвремя (относительно редко можно разрешить включать необработанную разметку HTML), это должно было быть по умолчанию.В новых языках шаблонов стало ясно, что включение возможности выхода из HTML является огромной ошибкой, которая вызывает бесконечные дыры в XSS, поэтому HTML-выход по умолчанию.

Вы можете заставить Smarty вести себя так, изменив значение по умолчанию модификаторы до html.( Не используйте htmlall, как они там предлагают, если вы действительно не знаете, что делаете, или это, скорее всего, испортит все ваши символы, не относящиеся к ASCII.)

Независимо от того,Вы не должны впадать в распространенную ошибку PHP - экранирование HTML или «дезинфекцию» для HTML на входе до того, как он будет обработан или помещен в базу данных.Это неправильное место для выполнения кодирования выходного каскада, и у вас возникнут всевозможные проблемы.Если вы хотите проверить свои входные данные, чтобы убедиться, что это именно то, что ожидает конкретное приложение, то это нормально, но отсеивание или экранирование «специальных» символов на этом этапе неуместно.

*: Другие аспекты XSS присутствуют, когда(а) вы на самом деле хотите, чтобы позволяли пользователям публиковать HTML, и в этом случае вам нужно сократить его до приемлемых элементов и атрибутов, что является сложным процессом, обычно выполняемым библиотекой, такой как HTML Purifier, и дажетогда были дыры.Альтернативные, более простые схемы разметки могут помочь.И (б) когда вы разрешаете пользователям загружать файлы, что очень сложно сделать безопасным.

1 голос
/ 07 мая 2010

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

Когда вы выводите их на веб-сайт, вы хотите экранировать специальные символы в HTML-коды, используя что-то вроде htmlspecialchars("my output & stuff", ENT_QUOTES, 'UTF-8') - обязательно укажитекодировка, которую вы используете.Эта строка будет переведена в my output &amp; stuff, чтобы браузер мог ее прочитать.

1 голос
/ 07 мая 2010

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

Для XSS (межсайтовый скриптинг) начните с HTML-кодирования выводимых данных.Опять же, анти-XSS библиотеки - ваш друг.

Один из текущих подходов - разрешить только очень ограниченное количество тегов и очистить их в процессе (белый список + очистка).

1 голос
/ 07 мая 2010

Вы хотите убедиться, что люди не смогут публиковать код JavaScript или страшный HTML в своих комментариях. Я предлагаю вам запретить что-либо кроме очень простой разметки.

Если комментарии не должны содержать разметки, выполните

echo htmlspecialchars($commentText);

должно хватить, но это очень грубо. Лучше было бы очистить все входные данные, прежде чем даже поместить их в вашу базу данных. Функция PHP strip_tags () может помочь вам начать работу.

Если вы хотите разрешить комментарии HTML, но в безопасности, вы можете попробовать Очиститель HTML .

0 голосов
/ 07 мая 2010

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

...