Этот набор регулярных выражений полностью защищает от межсайтовых скриптов? - PullRequest
6 голосов
/ 12 октября 2008

Что является примером чего-то опасного, что не будет поймано кодом ниже?

РЕДАКТИРОВАТЬ: После некоторых комментариев я добавил еще одну строку, прокомментированную ниже. Смотрите комментарий Винко в ответе Дэвида Гранта. Пока только Винко ответил на вопрос, который просит конкретные примеры, которые проскальзывают через эту функцию. Винко предоставил один, но я отредактировал код, чтобы закрыть эту дыру. Если другой из вас может подумать о другом конкретном примере, у вас будет мой голос!

public static string strip_dangerous_tags(string text_with_tags)
{
    string s = Regex.Replace(text_with_tags, @"<script", "<scrSAFEipt", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"</script", "</scrSAFEipt", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"<object", "</objSAFEct", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"</object", "</obSAFEct", RegexOptions.IgnoreCase);
    // ADDED AFTER THIS QUESTION WAS POSTED
    s = Regex.Replace(s, @"javascript", "javaSAFEscript", RegexOptions.IgnoreCase);

    s = Regex.Replace(s, @"onabort", "onSAFEabort", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onblur", "onSAFEblur", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onchange", "onSAFEchange", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onclick", "onSAFEclick", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"ondblclick", "onSAFEdblclick", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onerror", "onSAFEerror", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onfocus", "onSAFEfocus", RegexOptions.IgnoreCase);

    s = Regex.Replace(s, @"onkeydown", "onSAFEkeydown", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onkeypress", "onSAFEkeypress", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onkeyup", "onSAFEkeyup", RegexOptions.IgnoreCase);

    s = Regex.Replace(s, @"onload", "onSAFEload", RegexOptions.IgnoreCase);

    s = Regex.Replace(s, @"onmousedown", "onSAFEmousedown", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onmousemove", "onSAFEmousemove", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onmouseout", "onSAFEmouseout", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onmouseup", "onSAFEmouseup", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onmouseup", "onSAFEmouseup", RegexOptions.IgnoreCase);

    s = Regex.Replace(s, @"onreset", "onSAFEresetK", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onresize", "onSAFEresize", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onselect", "onSAFEselect", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onsubmit", "onSAFEsubmit", RegexOptions.IgnoreCase);
    s = Regex.Replace(s, @"onunload", "onSAFEunload", RegexOptions.IgnoreCase);

    return s;
}

Ответы [ 11 ]

48 голосов
/ 12 октября 2008

Этого никогда не бывает достаточно - белый, не черный список

Например, javascript: псевдо-URL может быть запутан сущностями HTML, вы забыли о <embed>, и в IE есть опасные свойства CSS, такие как behavior и expression.

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

Существует только два хороших способа защиты HTML:

  • преобразовать его в текст, заменив каждый < на &lt;.
    Если вы хотите разрешить пользователям вводить форматированный текст, вы можете использовать собственную разметку (например, разметку, как это делает SO).

  • анализирует HTML в DOM, проверяет каждый элемент и атрибут и удаляет все, что не занесено в белый список.
    Вам также необходимо проверить содержимое разрешенных атрибутов, таких как href (убедитесь, что URL-адреса используют безопасный протокол, заблокируйте все неизвестные протоколы).
    Как только вы очистите DOM, создайте из него новый действительный HTML. Никогда не работайте с HTML, как если бы это был текст, потому что неверная разметка, комментарии, сущности и т. Д. Могут легко обмануть ваш фильтр.

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

10 голосов
/ 12 октября 2008

Вам гораздо лучше превратить все < в &lt; и все > в &gt;, а затем конвертировать приемлемые теги обратно. Другими словами, белый список, не черный список.

7 голосов
/ 12 октября 2008

Как показывает Дэвид, нет простого способа защиты с помощью нескольких регулярных выражений, вы всегда можете что-то забыть, например, javascript: в вашем случае. Вам лучше избегать HTML-сущностей на выходе. Существует много дискуссий о том, как сделать это наилучшим образом, в зависимости от того, что вам действительно нужно разрешить, но несомненно то, что вашей функции недостаточно .

Джефф немного говорил об этом здесь .

4 голосов
/ 12 октября 2008
<a href="javascript:document.writeln('on' + 'unload' + ' and more malicious stuff here...');">example</a>

В любое время, когда вы можете написать строку в документе, открывается большая дверь.

Существует множество мест для внедрения вредоносных программ в HTML / JavaScript. По этой причине Facebook изначально не разрешал JavaScript в своей платформе приложений. Их решением было позднее реализовать компилятор разметки / скриптов, который позволит им серьезно отфильтровывать плохие вещи.

Как уже было сказано, внесите в белый список несколько тегов и атрибутов и удалите все остальное. Не помещайте в черный список несколько известных вредоносных атрибутов и разрешите все остальное.

3 голосов
/ 03 августа 2012

Я до сих пор не понял, почему разработчики хотят втиснуть плохой ввод в хороший ввод с помощью замены регулярного выражения. Если ваш сайт не является блогом и ему необходимо разрешить встроенный html или javascript или любой другой вид кода, отклоните неверный ввод и верните ошибку. Старая поговорка - «Мусор на входе - Мусор на выходе», почему вы хотите взять хорошую дымящуюся кучу какао и сделать ее съедобной?

Если ваш сайт не интернационализирован, зачем принимать юникод?

Если ваш сайт использует только POST, зачем принимать значения в кодировке URL?

Зачем принимать любой гекс? Зачем принимать HTML-объекты? Что пользователь вводит '& # x0A' или '& ampquot;'

Что касается регулярных выражений, их использование вполне допустимо, однако вам не нужно кодировать отдельное регулярное выражение для полной строки атаки. Вы можете отклонить много разных сигнатур атаки с помощью нескольких хорошо сконструированных шаблонов регулярных выражений:

patterns.put("xssAttack1", Pattern.compile("<script",Pattern.CASE_INSENSITIVE) );
patterns.put("xssAttack2", Pattern.compile("SRC=",Pattern.CASE_INSENSITIVE) );
patterns.put("xssAttack3", Pattern.compile("pt:al",Pattern.CASE_INSENSITIVE) );
patterns.put("xssAttack4", Pattern.compile("xss",Pattern.CASE_INSENSITIVE) );

<FRAMESET><FRAME SRC="javascript:alert('XSS');"></FRAMESET>
<DIV STYLE="width: expression(alert('XSS'));">
<LINK REL="stylesheet" HREF="javascript:alert('XSS');">
<IMG SRC="jav   ascript:alert('XSS');">    // hmtl allows embedded tabs...
<IMG SRC="jav&#x0A;ascript:alert('XSS');"> // hmtl allows embedded newline...
<IMG SRC="jav&#x0D;ascript:alert('XSS');"> // hmtl allows embedded carriage return...

Обратите внимание, что мои шаблоны не являются полной сигнатурой атаки, просто достаточно, чтобы определить, является ли значение вредоносным. Маловероятно, что пользователь введет «SRC =» или «pt: al». Это позволяет моим шаблонам регулярных выражений обнаруживать неизвестные атаки, в которых есть какой-либо из этих токенов.

Многие разработчики скажут вам, что вы не можете защитить сайт с помощью черного списка. Поскольку набор атак бесконечен, это в основном верно, однако, если вы проанализируете весь запрос (параметры, значения параметров, заголовки, файлы cookie) с черным списком, составленным на основе токенов, вы сможете выяснить, что такое атака. и что действительно. Помните, что злоумышленник, скорее всего, будет стрелять в вас, используя инструмент. Если вы должным образом укрепили свой сервер, он не будет знать, в какой среде вы работаете, и ему придется заполнить вас списками эксплойтов. Если он вас обидел, поместите злоумышленника или его IP-адрес в список карантина. Если у него есть инструмент с 50 000 эксплойтов, готовый поразить ваш сайт, сколько времени ему понадобится, если вы будете помещать в карантин его идентификатор или ip в течение 30 минут за каждое нарушение? По общему признанию, все еще есть воздействие, если злоумышленник использует ботнет для мультиплексирования своей атаки. Тем не менее, ваш сайт в итоге становится гораздо сложнее.

Теперь, проверив весь запрос на наличие вредоносного контента, вы теперь можете использовать проверки типа белого списка по длине, ссылкам / логическим именам для определения действительности запроса

Не забудьте реализовать какую-то защиту от CSRF. Возможно, медовый токен, и проверьте строку user-agent из предыдущих запросов, чтобы увидеть, изменилась ли она.

3 голосов
/ 10 января 2009

В качестве примера атаки, которая проходит через это:

  <div style="color: expression('alert(4)')">

Бесстыдная вилка: Проект Caja определяет белые списки элементов и атрибутов HTML, чтобы он мог контролировать, как и когда выполняются сценарии в HTML.

См. Проект на http://code.google.com/p/google-caja/ и белые списки являются файлами JSON в http://code.google.com/p/google-caja/source/browse/#svn/trunk/src/com/google/caja/lang/html а также http://code.google.com/p/google-caja/source/browse/#svn/trunk/src/com/google/caja/lang/css

3 голосов
/ 13 октября 2008

Взгляните на таблицу XSS в http://ha.ckers.org/xss.html, это не полный список, а хорошее начало.

На ум приходит image

Вы также забыли onmouseover и тег style.

Самое простое, что можно сделать на самом деле - это сущность, избегающая . Если вектор не может правильно отображаться, неполный черный список не имеет значения.

3 голосов
/ 12 октября 2008

Хотя я не могу привести конкретный пример того, почему нет, я собираюсь пойти дальше и прямо сказать «нет». Это больше по принципу. Regex's - удивительный инструмент, но их следует использовать только для определенных задач. Они отлично подходят для сопоставления данных и поиска.

Однако они не являются хорошим инструментом для обеспечения безопасности. Слишком легко испортить регулярное выражение и сделать его только частично правильным. Хакеры могут найти много места для маневра в плохо или даже хорошо сконструированном регулярном выражении. Я бы попробовал другой путь, чтобы предотвратить межсайтовый скриптинг.

2 голосов
/ 12 октября 2008

Пробелы делают вас уязвимыми. Читать это .

1 голос
/ 13 октября 2008

С другой точки зрения, что происходит, когда кто-то хочет иметь «javascript», «functionload» или «visionblurred» в том, что они представляют? Это может происходить в большинстве мест по ряду причин ... Из того, что я понимаю, они станут 'javaSAFEscript', 'functionSAFEload' и 'visionSAFEblurred' (!!).

Если это может относиться к вам, и вы застряли с подходом черного списка, обязательно используйте точно совпадающие регулярные выражения, чтобы не раздражать пользователя. Другими словами, будьте в оптимальной точке между безопасностью и удобством использования, ставя под угрозу как можно меньше.

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