Подтвердить что ты не робот

Лучший способ справиться с безопасностью и избежать XSS с введенными пользователями URL-адресами

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

Это представляет собой высокий риск взлома XSS - пользователь может потенциально ввести javascript, который выполняет другой пользователь. Поскольку мы храним конфиденциальные данные, важно, чтобы это никогда не происходило.

Каковы наилучшие методы борьбы с этим? Является ли какой-либо безопасный белый список или шаблон эвакуации одним достаточно хорошим?

Любые рекомендации по перенаправлению (сообщение "ссылка выходит за пределы нашего сайта" на странице предупреждения, например, после ссылки)

Есть ли аргумент для того, чтобы вообще не поддерживать ссылки, введенные пользователем?


Разъяснение:

В основном наши пользователи хотят вводить:

stackoverflow.com

И передайте его другому пользователю:

<a href="#" onclick="location.href='http://stackoverflow.com'; return false;">stackoverflow.com</a>

Я действительно беспокоюсь о том, что они используют это в XSS-хаке. То есть они вводят:

оповещения ( 'взломан!');

Таким образом, другие пользователи получают эту ссылку:

<a href="alert('hacked!');">stackoverflow.com</a>

Мой пример - просто объяснить риск - я хорошо знаю, что javascript и URL-адреса - это разные вещи, но, позволяя им вводить последние, они могут выполнить первый.

Вы были бы удивлены, сколько сайтов вы можете сломать с этим трюком - HTML еще хуже. Если они знают, что имеют дело со ссылками, они также знают, что нужно санировать <iframe>, <img> и умные ссылки CSS?

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

4b9b3361

Ответ 1

Если вы считаете, что URL-адреса не могут содержать код, подумайте еще раз!

https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet

Прочитайте это и плачьте.

Вот как мы это делаем на переполнении стека:

/// <summary>
/// returns "safe" URL, stripping anything outside normal charsets for URL
/// </summary>
public static string SanitizeUrl(string url)
{
    return Regex.Replace(url, @"[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]", "");
}

Ответ 2

Процесс визуализации ссылки "безопасный" должен пройти три или четыре шага:

  • Unescape/re-encode строка, которую вы дали (RSnake задокументировал ряд трюков в http://ha.ckers.org/xss.html, которые используют escape-коды и кодировки UTF).
  • Очистить ссылку: регулярные выражения - это хороший старт - убедитесь, что вы усекаете строку или отбрасываете ее, если она содержит "(или что-то, что вы используете для закрытия атрибутов в своем выходе); Если вы делаете ссылки только в качестве ссылок на другую информацию вы также можете принудительно выполнить протокол в конце этого процесса - если часть перед первым двоеточием не является" http "или" https ", тогда добавьте" http://" в начало. Это позволяет вам для создания полезных ссылок из неполного ввода, поскольку пользователь вводит в браузер и дает вам последний снимок при отключении любого вреда, который кто-то пытался прокрасться.
  • Убедитесь, что результат - хорошо сформированный URL (протокол://host.domain [: port] [/path] [/[файл]] [? queryField = queryValue] [#anchor]).
  • Возможно, проверьте результат на черный список сайта или попробуйте найти его с помощью какой-либо проверки на наличие вредоносных программ.

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

Ответ 3

Используйте библиотеку, такую ​​как API OWASP-ESAPI:

Прочтите следующее:

Например:

$url = "http://stackoverflow.com"; // e.g., $_GET["user-homepage"];
$esapi = new ESAPI( "/etc/php5/esapi/ESAPI.xml" ); // Modified copy of ESAPI.xml
$sanitizer = ESAPI::getSanitizer();
$sanitized_url = $sanitizer->getSanitizedURL( "user-homepage", $url );

Другим примером является использование встроенной функции. PHP filter_var - пример:

$url = "http://stackoverflow.com"; // e.g., $_GET["user-homepage"];
$sanitized_url = filter_var($url, FILTER_SANITIZE_URL);

Используя filter_var разрешает javascript-вызовы и отфильтровывает схемы, которые не являются http и https. Использование OWASP ESAPI Sanitizer, вероятно, лучший вариант.

Еще один пример - это код из WordPress:

Кроме того, поскольку нет способа узнать, где ссылки URL (т.е. может быть действительным URL-адресом, но содержимое URL-адреса может быть озорным), у Google есть безопасный просмотр API, который вы можете вызвать:

Перемещение собственного регулярного выражения для санитарии проблематично по нескольким причинам:

  • Если вы не Джон Скотт, код будет иметь ошибки.
  • Существующие API имеют много часов обзора и тестирования позади них.
  • Существующие API-проверки правильности URL-адресов рассматривают интернационализацию.
  • Существующие API будут обновляться с появляющимися стандартами.

Другие вопросы, которые необходимо учитывать:

  • Какие схемы вы разрешаете (допустимы file:/// и telnet://)?
  • Какие ограничения вы хотите разместить в содержании URL-адреса (допустимы ли URL-адреса вредоносных программ)?

Ответ 4

Просто HTMLEncode ссылки при их выводе. Убедитесь, что вы не разрешаете ссылки javascript:. (Лучше всего иметь белый список протоколов, которые принимаются, например, http, https и mailto.)

Ответ 5

Вы не указываете язык своего приложения, я буду предполагать ASP.NET, и для этого вы можете использовать Microsoft Anti-Cross Site Скриптовая библиотека

Он очень прост в использовании, все, что вам нужно, это include и вот оно:)

Пока вы на эту тему, почему бы не прочитать прочитанный Рекомендации по дизайну для защищенных веб-приложений

Если какой-либо другой язык.... если есть библиотека для ASP.NET, должен быть доступен также для другого типа языка (PHP, Python, ROR и т.д.)

Ответ 6

Как не показывать их как ссылку? Просто используйте текст.

В сочетании с предупреждением, чтобы действовать на свой страх и риск, может быть достаточно.

дополнение - см. также Должен ли я дезинфицировать HTML-разметку для размещенной CMS? для обсуждения дезинфекции пользовательского ввода

Ответ 7

Вы можете использовать шестнадцатеричный код для преобразования всего URL-адреса и отправки его на ваш сервер. Таким образом, клиент не будет понимать контент с первого взгляда. После прочтения содержимого вы можете декодировать контент URL =? и отправить его в браузер.

Ответ 8

Разрешить URL-адрес и разрешить JavaScript - это две разные вещи.