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

Исключение HTML-объектов в строковых литералах JavaScript в блоке <script>

С одной стороны, если у меня есть

<script>
var s = 'Hello </script>';
console.log(s);
</script>

браузер рано разорвет блок <script>, и в основном я получаю эту страницу.

С другой стороны, значение строки может исходить от пользователя (скажем, через ранее представленную форму, и теперь строка заканчивается вставкой в ​​блок <script> в качестве литерала), поэтому вы можете ожидать все в этой строке, включая злонамеренно созданные теги. Теперь, если я удаляю строковый литерал с помощью htmlentities() при создании страницы, значение s будет содержать экранированные объекты буквально, то есть s будет выводить

Hello &lt;/script&gt;

что не является желательным поведением в этом случае.

Одним из способов правильного экранирования строк JS в блоке <script> является экранирование косой черты, если оно следует за левой угловой скобкой или просто всегда выходит из косой черты, т.е.

var s = 'Hello <\/script>';

Кажется, что это нормально работает.

Затем возникает вопрос о JS-коде в обработчиках событий HTML, который также можно легко сломать, например.

<div onClick="alert('Hello ">')"></div>

выглядит действительным сначала, но ломается в большинстве (или всех?) браузеров. Это, очевидно, требует полной кодировки сущности HTML.

Мой вопрос: какова лучшая/стандартная практика для надлежащего покрытия всех вышеперечисленных ситуаций - то есть JS в блоке script, JS в обработчиках событий - если ваш JS-код частично может быть сгенерирован на стороне сервера и может потенциально могут содержать вредоносные данные?

4b9b3361

Ответ 1

Следующие символы могут помешать работе с парсером HTML или Javascript и должны быть экранированы в строковых литералах: <, >, ", ', \, и &.

В блоке script с использованием escape-символа, как вы выяснили, работает. Метод конкатенации (</scr' + 'ipt>') может быть трудно читаемым.

var s = 'Hello <\/script>';

Для встроенного Javascript в HTML вы можете использовать объекты:

<div onClick="alert('Hello &quot;>')">click me</div>

Демо: http://jsfiddle.net/ThinkingStiff/67RZH/

Метод, который работает как в блоках <script>, так и в встроенном Javascript, \uxxxx, где xxxx - шестнадцатеричный код символа.

  • < - \u003c
  • > - \u003e
  • " - \u0022
  • ' - \u0027
  • \ - \u005c
  • & - \u0026

Демо: http://jsfiddle.net/ThinkingStiff/Vz8n7/

HTML:

<div onClick="alert('Hello \u0022>')">click me</div>

<script>
    var s = 'Hello \u003c/script\u003e';
alert( s );
</script>   

Ответ 2

(отредактируйте - как-то не заметили, что вы уже упомянули слэш-побег в своем вопросе уже...)

ОК, чтобы вы знали, как избежать косой черты.

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

<div onClick='alert("Hello \"")'>test</div>

Но это все помогает твоей жизни. Просто не используйте встроенные обработчики событий! Или, если вам абсолютно необходимо, попросите их вызвать функцию, определенную в другом месте.

Вообще говоря, есть несколько причин, по которым ваш серверный код должен писать javascript. Не создавайте сценарии с сервера - передавайте данные в предварительно написанные сценарии.

(оригинал)

Вы можете избежать чего-либо в строковом литерале JS с обратным слэшем (это иначе не специальный escape-символ):

var s = 'Hello <\/script>';

Это также оказывает положительное влияние на то, чтобы не интерпретировать его как html. Таким образом, вы можете сделать замену одеяла "/" на "\/", чтобы не повредить эффект.

В целом, однако, я обеспокоен тем, что у вас будут данные, представленные пользователем, как строковый литерал в javascript. Вы генерируете код javascript на сервере? Почему бы просто не передавать данные как JSON или атрибут "данные" HTML или что-то вместо этого?

Ответ 3

Я бы сказал, что лучше всего избегать встроенного JS.

Поместите JS-код в отдельный файл и включите его с атрибутом src

<script src="path/to/file.js"></script>

и использовать его для установки обработчиков событий изнутри isntead для размещения этих в HTML.

//jquery example
$('div.something').on('click', function(){
    alert('Hello>');
})

Ответ 4

Вот как я это делаю:

function encode(r){
return r.replace(/[\x26\x0A\<>'"]/g,function(r){return"&#"+r.charCodeAt(0)+";"})
}

var myString='Encode HTML entities!\n"Safe" escape <script></'+'script> & other tags!';

test.value=encode(myString);

testing.innerHTML=encode(myString);

/*************
* \x26 is &ampersand (it has to be first),
* \x0A is newline,
*************/
<textarea id=test rows="9" cols="55"></textarea>

<div id="testing">www.WHAK.com</div>

Ответ 5

Большинство людей используют этот трюк:

var s = 'Hello </scr' + 'ipt>';