Передача возможно небезопасного пользовательского ввода из скрытого поля ввода в DOM - PullRequest
1 голос
/ 27 февраля 2012

Ниже приведен упрощенный пример страницы, которую пользователь создал на сайте (они создали ее, заполнив форму, а затем получили URL-адрес для страницы; ниже приведен HTML-код для страницы, которую он создал).

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

Каков наилучший способ предотвратить подобные вещи?Значение #sourceinput ранее было введено тем же или другим пользователем, который просматривал страницу ниже, и пользовательский ввод не был отфильтрован для удаления тегов.(Фактический случай включает в себя плагин jquery.tooltip.js и его обратный вызов bodyHandler; при наведении мыши обратный вызов bodyHandler получает скрытый ввод и отображает его пользователю.)

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

Другим способом было бы убрать теги в Javascript, но некоторые из них не кажутся эффективными на 100%:

Убрать HTML из текста JavaScript

Есть ли какая-то лучшая практика, которую я пропускаю, или это два лучших способа?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<head>
<title></title>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script>google.load("jquery", "1.7.1");</script>
<script>
$(document).ready(function() {
  var badHTML = $('#sourceinput').val();
  $('#destinationdiv').html( badHTML );
  //$('#destinationdiv').text( badHTML );
});
</script>
</head>

<body>
<input type="hidden" id="sourceinput" value="&lt;script&gt;alert&#40;&#039;hi&#039;&#41;;&lt;/script&gt;" />
<div id="destinationdiv" style="width:10px;height:10px;background-color:red;"></div>
</body>
</html>

ОБНОВЛЕНИЕРешение, с которым я сейчас работаю, состоит из трех частей:

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

  2. Когда отображается страница, созданная пользователем, вместо помещения того, что пользователь ввел в атрибут входного значения, я помещаю их ввод вdiv.

  3. Я извлекаю значение из этого div, используя .text () (не .html ()).Затем я запускаю это через функцию подчеркивания (см. Ниже).

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

Ответы [ 3 ]

0 голосов
/ 28 февраля 2012

Я бы сказал, что вы прокомментировали (лучше использовать text () из jquery).Это гарантирует, что текст останется тем, что вы хотите.Фильтрация или удаление могут иметь нежелательные побочные эффекты, такие как удаление математического выражения во входных данных ("x is <5"). </p>

0 голосов
/ 29 февраля 2012

Ничего не делать.

Вы пытаетесь защитить пользователя от самого себя . Пользователь А не может нанести вред пользователю Б. И, как бы то ни было, пользователь А может также ввести javascript:alert('hi') в адресную строку и сам xss. И независимо от того, какую функцию Javascript вы создаете, опытный пользователь всегда может ее обойти. В общем, это бессмысленное преследование.

Теперь, если вы начнете сохранять то, что пользователь ввел на стороне сервера, то вам определенно следует отфильтровать вещи. Не создавайте ничего самостоятельно. В зависимости от вашего языка на стороне сервера, есть несколько вариантов. AntiSammy OWASP является одним из таких решений.

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

0 голосов
/ 27 февраля 2012

Вот функция escape, используемая Underscore.js , если вы не хотите использовать всю библиотеку функций Underscore:

var escape = function(string) {
    return (''+string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
};

Используется как

var safe_html = escape("<b>Potentially unsafe text</b>"); // "&lt;b&gt;hello&lt;&#x2F;b&gt;"
$("#destination").html(safe_html);

Он написан хорошо и, как известно, работает, поэтому я бы посоветовал не катать свои собственные.

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