Unescape HTML-об'єктів у Javascript?


177

У мене є код Javascript, який зв’язується із сервісом XML-RPC. XML-RPC повертає рядки форми:

<img src='myimage.jpg'>

Однак, коли я використовую Javascript для вставки рядків у HTML, вони відображаються буквально. Я не бачу зображення, я буквально бачу рядок:

<img src='myimage.jpg'>

Я здогадуюсь, що HTML переходить через канал XML-RPC.

Як я можу скасувати рядок у Javascript? Я спробував методи на цій сторінці, безуспішно: http://paulschreiber.com/blog/2008/09/20/javascript-how-to-unescape-html-entities/

Які ще способи діагностувати проблему?


1
Спробуйте це: stackoverflow.com/questions/4480757/…
XP1

Відповіді:


177

EDIT: Ви повинні використовувати API DOMParser, як пропонує Володимир , я редагував свою попередню відповідь, оскільки розміщена функція вводила вразливість безпеки.

Наступний фрагмент - це старий код відповіді з невеликою модифікацією: використання textareaзамість divзменшує вразливість XSS, але це все ще проблематично в IE9 та Firefox.

function htmlDecode(input){
  var e = document.createElement('textarea');
  e.innerHTML = input;
  // handle case of empty input
  return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}

htmlDecode("&lt;img src='myimage.jpg'&gt;"); 
// returns "<img src='myimage.jpg'>"

В основному я створюю DOM елемент програмно, присвоюю кодований HTML його внутрішнійHTML та отримую nodeValue з текстового вузла, створеного у внутрішній HTMLML-вставці. Оскільки він просто створює елемент, але ніколи не додає його, жоден HTML сайт не змінюється.

Він буде працювати між веб-браузером (включаючи старіші браузери) та приймати всі елементи символів HTML .

EDIT: Стара версія цього коду не працювала в IE з порожніми входами, про що свідчить тут на jsFiddle (перегляд в IE). Наведена вище версія працює з усіма входами.

ОНОВЛЕННЯ: Здається, це не працює з великими рядками, а також вводить вразливість безпеки , дивіться коментарі.


Зрозумів, ти змінив на ', тож дозволь мені видалити коментар назад, thx, його працює чудово, +1
ВАС

1
@ S.Mark: &apos;не належить до об'єктів HTML 4, ось чому! w3.org/TR/html4/sgml/entities.html fishbowl.pastiche.org/2003/07/01/the_curse_of_apos
CMS

2
Дивіться також примітку @ kender про низьку безпеку такого підходу.
Йосип Туріан

2
Дивіться мою записку до @kender про те, що він зробив тестування;)
Roatin Marth

24
Ця функція загрожує безпеці, код JavaScript запускається навіть незважаючи на те, що елемент не буде додано до DOM. Тож це лише щось, що потрібно використовувати, якщо довіряти рядок введення. Я додав власну відповідь, що пояснює проблему та забезпечує безпечне рішення. Як побічний ефект, результат не відключається, якщо існує декілька текстових вузлів.
Володимир Палант

375

Більшість наведених тут відповідей мають величезний недолік: якщо рядок, яку ви намагаєтеся перетворити, не довіряється, то у вас з’явиться вразливість міжсайтового сценарію (XSS) . Для функції у прийнятій відповіді врахуйте наступне:

htmlDecode("<img src='dummy' onerror='alert(/xss/)'>");

Рядок тут містить несказаний тег HTML, тому замість того, щоб розшифрувати що-небудь, htmlDecodeфункція фактично запустить код JavaScript, визначений всередині рядка.

Цього можна уникнути, використовуючи DOMParser, який підтримується у всіх сучасних браузерах :

function htmlDecode(input) {
  var doc = new DOMParser().parseFromString(input, "text/html");
  return doc.documentElement.textContent;
}

console.log(  htmlDecode("&lt;img src='myimage.jpg'&gt;")  )    
// "<img src='myimage.jpg'>"

console.log(  htmlDecode("<img src='dummy' onerror='alert(/xss/)'>")  )  
// ""

Ця функція гарантовано не запускає жоден код JavaScript як побічний ефект. Будь-які теги HTML будуть ігноровані, повертається лише текстовий вміст.

Примітка сумісності : для розбору HTML DOMParserпотрібен принаймні Chrome 30, Firefox 12, Opera 17, Internet Explorer 10, Safari 7.1 або Microsoft Edge. Таким чином, всі браузери без підтримки проходять повз свій EOL, і станом на 2017 рік єдиними, які ще можна спостерігати в дикій природі, є старіші версії Internet Explorer і Safari (зазвичай це все ще недостатньо багато для того, щоб турбувати).


19
Я вважаю, що ця відповідь найкраща, тому що вона згадувала вразливість XSS.
Константин Ван

2
Зауважте, що (згідно з вашою довідкою) DOMParserне підтримував "text/html"Firefox 12.0, і все ж є деякі останні версії браузерів, які навіть не підтримуютьDOMParser.prototype.parseFromString() . Згідно з вашою довідкою, DOMParserце все ще експериментальна технологія, і в стендах використовується innerHTMLвластивість, яка, як ви також вказали у відповідь на мій підхід , має цю вразливість XSS (яку повинні виправити постачальники браузерів).
PointedEars

4
@PointedEars: Кого хвилює Firefox 12 у 2016 році? Проблемними є Internet Explorer до 9.0 та Safari до 7.0. Якщо ви можете дозволити собі не підтримувати їх (що, сподіваємось, незабаром стане всім), то DOMParser - найкращий вибір. Якщо ні - так, лише обробні об'єкти були б варіантом.
Володимир Палант

4
@PointedEars: <script>теги, які не виконуються, не є механізмом захисту, це правило просто уникає складних проблем із тимчасовим встановленням, якщо встановлення innerHTMLможе запускати синхронні сценарії як побічний ефект. Санітизація HTML-коду є хитрою справою і innerHTMLнавіть не намагається - вже тому, що веб-сторінка насправді має намір встановити вбудовані обробники подій. Це просто не механізм, призначений для небезпечних даних, повної зупинки.
Володимир Палант

1
@ ИльяЗеленько: Ви плануєте використовувати цей код у вузькому циклі, або чому важлива продуктивність? Ваша відповідь знову вразлива до XSS, чи справді вона того варта?
Володимир Палант

37

Якщо ви використовуєте jQuery:

function htmlDecode(value){ 
  return $('<div/>').html(value).text(); 
}

В іншому випадку використовуйте суто програмний продукт Encoder Object , який має чудову htmlDecode()функцію.


59
Не використовуйте (повторюйте НЕ) це використання для створеного користувачем контенту, крім вмісту, створеного цим користувачем. Якщо у значенні є тег <script>, вміст сценарію буде виконано!
Мальволіо

Я не можу знайти ліцензію на це ніде на сайті. Чи знаєте ви, що таке ліцензія?
TRiG

У заголовку джерела є ліцензія, це GPL.
Кріс Фулстоу

6
ТАК, ця функція відкриває шлях для XSS: спробуйте htmlDecode ("<script> alert (12) </script> 123 & gt;")
Дініс Крус

яке значення $ ('<div />') ?
Ехо Ян

13

Трюк полягає в тому, щоб використовувати силу браузера для декодування спеціальних символів HTML, але не дозволяти браузеру виконувати результати так, ніби це був фактичний html ... Ця функція використовує регулярний вираз для визначення та заміни закодованих символів HTML, один символ зараз.

function unescapeHtml(html) {
    var el = document.createElement('div');
    return html.replace(/\&[#0-9a-z]+;/gi, function (enc) {
        el.innerHTML = enc;
        return el.innerText
    });
}

Регекс можна порівняти трохи жорсткіше, /\&#?[0-9a-z]+;/giоскільки # повинен взагалі відображатися як другий символ.
TheAtomicOption

Це найкраща відповідь. Уникає вразливості XSS і не знімає теги HTML.
Еммануїл

6

Відповідь CMS працює добре, якщо тільки HTML, який ви хочете відмітити, дуже довгий, довший 65536 знаків. Оскільки тоді в Chrome внутрішній HTML розбивається на багато дочірніх вузлів, кожен з яких максимум 65536, і вам потрібно їх об'єднати. Ця функція працює також для дуже довгих рядків:

function unencodeHtmlContent(escapedHtml) {
  var elem = document.createElement('div');
  elem.innerHTML = escapedHtml;
  var result = '';
  // Chrome splits innerHTML into many child nodes, each one at most 65536.
  // Whereas FF creates just one single huge child node.
  for (var i = 0; i < elem.childNodes.length; ++i) {
    result = result + elem.childNodes[i].nodeValue;
  }
  return result;
}

Дивіться цю відповідь про innerHTMLмаксимальну довжину для отримання додаткової інформації: https://stackoverflow.com/a/27545633/694469


3

Це не пряма відповідь на ваше запитання, але чи не було б краще, щоб ваш RPC повертав якусь структуру (будь то XML чи JSON чи інше) з цими даними зображення (URL-адресами у вашому прикладі) всередині цієї структури?

Тоді ви можете просто проаналізувати його у вашому javascript і створити сам <img>JavaScript.

Структура, яку ви отримуєте від RPC, може виглядати так:

{"img" : ["myimage.jpg", "myimage2.jpg"]}

Я думаю, що так краще, оскільки введення коду, який надходить із зовнішнього джерела на вашу сторінку, не виглядає дуже безпечним. Уявляючи, що хтось захоплює ваш XML-RPC-скрипт і вкладає туди щось, чого б вам не хотілося (навіть якийсь JavaScript ...)


Чи має підхід @CMS вище вказаний недолік безпеки?
Йосип Туріан

Я щойно перевірив наступний аргумент, переданий на htmlDecode fuction: htmlDecode ("& lt; img src = 'myimage.jpg' & gt; & lt; script & gt; document.write ('xxxxx'); & lt; / script & gt;"), і він створює <script> </script> елемент, який може бути поганим, імхо. І я все ще думаю, що повернути структуру замість тексту, який потрібно вставити, краще, ви можете добре впоратися з помилками, наприклад.
Кендер

1
Я просто спробував htmlDecode("&lt;img src='myimage.jpg'&gt;&lt;script&gt;alert('xxxxx');&lt;/script&gt;")і нічого не вийшло. Я повернув розшифрований HTML-рядок, як очікувалося.
Roatin Marth

2

Відповідь Кріса приємна та елегантна, але вона не вдається, якщо значення не визначене . Просто просте вдосконалення робить його міцним:

function htmlDecode(value) {
   return (typeof value === 'undefined') ? '' : $('<div/>').html(value).text();
}

Якщо покращити, то зробіть:return (typeof value !== 'string') ? '' : $('<div/>').html(value).text();
SynCap

2

Запрошуємо вас ... просто месенджер ... повний кредит припадає на ourcodeworld.com, посилання нижче.

window.htmlentities = {
        /**
         * Converts a string to its html characters completely.
         *
         * @param {String} str String with unescaped HTML characters
         **/
        encode : function(str) {
            var buf = [];

            for (var i=str.length-1;i>=0;i--) {
                buf.unshift(['&#', str[i].charCodeAt(), ';'].join(''));
            }

            return buf.join('');
        },
        /**
         * Converts an html characterSet into its original character.
         *
         * @param {String} str htmlSet entities
         **/
        decode : function(str) {
            return str.replace(/&#(\d+);/g, function(match, dec) {
                return String.fromCharCode(dec);
            });
        }
    };

Повний кредит: https://ourcodeworld.com/articles/read/188/encode-and-decode-html-entities-using-pure-javascript


2

Це найбільш комплексне рішення, яке я намагався поки що:

const STANDARD_HTML_ENTITIES = {
    nbsp: String.fromCharCode(160),
    amp: "&",
    quot: '"',
    lt: "<",
    gt: ">"
};

const replaceHtmlEntities = plainTextString => {
    return plainTextString
        .replace(/&#(\d+);/g, (match, dec) => String.fromCharCode(dec))
        .replace(
            /&(nbsp|amp|quot|lt|gt);/g,
            (a, b) => STANDARD_HTML_ENTITIES[b]
        );
};

"Найповніший"? Ви спробували запустити його на фактично всебічному тестовому наборі ?
Дан Даскалеску

1

Я був досить божевільний, щоб пройти та зробити цю функцію, яка повинна бути досить, якщо не повністю, вичерпною:

function removeEncoding(string) {
    return string.replace(/&Agrave;/g, "À").replace(/&Aacute;/g, "Á").replace(/&Acirc;/g, "Â").replace(/&Atilde;/g, "Ã").replace(/&Auml;/g, "Ä").replace(/&Aring;/g, "Å").replace(/&agrave;/g, "à").replace(/&acirc;/g, "â").replace(/&atilde;/g, "ã").replace(/&auml;/g, "ä").replace(/&aring;/g, "å").replace(/&AElig;/g, "Æ").replace(/&aelig;/g, "æ").replace(/&szlig;/g, "ß").replace(/&Ccedil;/g, "Ç").replace(/&ccedil;/g, "ç").replace(/&Egrave;/g, "È").replace(/&Eacute;/g, "É").replace(/&Ecirc;/g, "Ê").replace(/&Euml;/g, "Ë").replace(/&egrave;/g, "è").replace(/&eacute;/g, "é").replace(/&ecirc;/g, "ê").replace(/&euml;/g, "ë").replace(/&#131;/g, "ƒ").replace(/&Igrave;/g, "Ì").replace(/&Iacute;/g, "Í").replace(/&Icirc;/g, "Î").replace(/&Iuml;/g, "Ï").replace(/&igrave;/g, "ì").replace(/&iacute;/g, "í").replace(/&icirc;/g, "î").replace(/&iuml;/g, "ï").replace(/&Ntilde;/g, "Ñ").replace(/&ntilde;/g, "ñ").replace(/&Ograve;/g, "Ò").replace(/&Oacute;/g, "Ó").replace(/&Ocirc;/g, "Ô").replace(/&Otilde;/g, "Õ").replace(/&Ouml;/g, "Ö").replace(/&ograve;/g, "ò").replace(/&oacute;/g, "ó").replace(/&ocirc;/g, "ô").replace(/&otilde;/g, "õ").replace(/&ouml;/g, "ö").replace(/&Oslash;/g, "Ø").replace(/&oslash;/g, "ø").replace(/&#140;/g, "Œ").replace(/&#156;/g, "œ").replace(/&#138;/g, "Š").replace(/&#154;/g, "š").replace(/&Ugrave;/g, "Ù").replace(/&Uacute;/g, "Ú").replace(/&Ucirc;/g, "Û").replace(/&Uuml;/g, "Ü").replace(/&ugrave;/g, "ù").replace(/&uacute;/g, "ú").replace(/&ucirc;/g, "û").replace(/&uuml;/g, "ü").replace(/&#181;/g, "µ").replace(/&#215;/g, "×").replace(/&Yacute;/g, "Ý").replace(/&#159;/g, "Ÿ").replace(/&yacute;/g, "ý").replace(/&yuml;/g, "ÿ").replace(/&#176;/g, "°").replace(/&#134;/g, "†").replace(/&#135;/g, "‡").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&#177;/g, "±").replace(/&#171;/g, "«").replace(/&#187;/g, "»").replace(/&#191;/g, "¿").replace(/&#161;/g, "¡").replace(/&#183;/g, "·").replace(/&#149;/g, "•").replace(/&#153;/g, "™").replace(/&copy;/g, "©").replace(/&reg;/g, "®").replace(/&#167;/g, "§").replace(/&#182;/g, "¶").replace(/&Alpha;/g, "Α").replace(/&Beta;/g, "Β").replace(/&Gamma;/g, "Γ").replace(/&Delta;/g, "Δ").replace(/&Epsilon;/g, "Ε").replace(/&Zeta;/g, "Ζ").replace(/&Eta;/g, "Η").replace(/&Theta;/g, "Θ").replace(/&Iota;/g, "Ι").replace(/&Kappa;/g, "Κ").replace(/&Lambda;/g, "Λ").replace(/&Mu;/g, "Μ").replace(/&Nu;/g, "Ν").replace(/&Xi;/g, "Ξ").replace(/&Omicron;/g, "Ο").replace(/&Pi;/g, "Π").replace(/&Rho;/g, "Ρ").replace(/&Sigma;/g, "Σ").replace(/&Tau;/g, "Τ").replace(/&Upsilon;/g, "Υ").replace(/&Phi;/g, "Φ").replace(/&Chi;/g, "Χ").replace(/&Psi;/g, "Ψ").replace(/&Omega;/g, "Ω").replace(/&alpha;/g, "α").replace(/&beta;/g, "β").replace(/&gamma;/g, "γ").replace(/&delta;/g, "δ").replace(/&epsilon;/g, "ε").replace(/&zeta;/g, "ζ").replace(/&eta;/g, "η").replace(/&theta;/g, "θ").replace(/&iota;/g, "ι").replace(/&kappa;/g, "κ").replace(/&lambda;/g, "λ").replace(/&mu;/g, "μ").replace(/&nu;/g, "ν").replace(/&xi;/g, "ξ").replace(/&omicron;/g, "ο").replace(/&piρ;/g, "ρ").replace(/&rho;/g, "ς").replace(/&sigmaf;/g, "ς").replace(/&sigma;/g, "σ").replace(/&tau;/g, "τ").replace(/&phi;/g, "φ").replace(/&chi;/g, "χ").replace(/&psi;/g, "ψ").replace(/&omega;/g, "ω").replace(/&bull;/g, "•").replace(/&hellip;/g, "…").replace(/&prime;/g, "′").replace(/&Prime;/g, "″").replace(/&oline;/g, "‾").replace(/&frasl;/g, "⁄").replace(/&weierp;/g, "℘").replace(/&image;/g, "ℑ").replace(/&real;/g, "ℜ").replace(/&trade;/g, "™").replace(/&alefsym;/g, "ℵ").replace(/&larr;/g, "←").replace(/&uarr;/g, "↑").replace(/&rarr;/g, "→").replace(/&darr;/g, "↓").replace(/&barr;/g, "↔").replace(/&crarr;/g, "↵").replace(/&lArr;/g, "⇐").replace(/&uArr;/g, "⇑").replace(/&rArr;/g, "⇒").replace(/&dArr;/g, "⇓").replace(/&hArr;/g, "⇔").replace(/&forall;/g, "∀").replace(/&part;/g, "∂").replace(/&exist;/g, "∃").replace(/&empty;/g, "∅").replace(/&nabla;/g, "∇").replace(/&isin;/g, "∈").replace(/&notin;/g, "∉").replace(/&ni;/g, "∋").replace(/&prod;/g, "∏").replace(/&sum;/g, "∑").replace(/&minus;/g, "−").replace(/&lowast;/g, "∗").replace(/&radic;/g, "√").replace(/&prop;/g, "∝").replace(/&infin;/g, "∞").replace(/&OEig;/g, "Œ").replace(/&oelig;/g, "œ").replace(/&Yuml;/g, "Ÿ").replace(/&spades;/g, "♠").replace(/&clubs;/g, "♣").replace(/&hearts;/g, "♥").replace(/&diams;/g, "♦").replace(/&thetasym;/g, "ϑ").replace(/&upsih;/g, "ϒ").replace(/&piv;/g, "ϖ").replace(/&Scaron;/g, "Š").replace(/&scaron;/g, "š").replace(/&ang;/g, "∠").replace(/&and;/g, "∧").replace(/&or;/g, "∨").replace(/&cap;/g, "∩").replace(/&cup;/g, "∪").replace(/&int;/g, "∫").replace(/&there4;/g, "∴").replace(/&sim;/g, "∼").replace(/&cong;/g, "≅").replace(/&asymp;/g, "≈").replace(/&ne;/g, "≠").replace(/&equiv;/g, "≡").replace(/&le;/g, "≤").replace(/&ge;/g, "≥").replace(/&sub;/g, "⊂").replace(/&sup;/g, "⊃").replace(/&nsub;/g, "⊄").replace(/&sube;/g, "⊆").replace(/&supe;/g, "⊇").replace(/&oplus;/g, "⊕").replace(/&otimes;/g, "⊗").replace(/&perp;/g, "⊥").replace(/&sdot;/g, "⋅").replace(/&lcell;/g, "⌈").replace(/&rcell;/g, "⌉").replace(/&lfloor;/g, "⌊").replace(/&rfloor;/g, "⌋").replace(/&lang;/g, "⟨").replace(/&rang;/g, "⟩").replace(/&loz;/g, "◊").replace(/&#039;/g, "'").replace(/&amp;/g, "&").replace(/&quot;/g, "\"");
}

Використовується так:

let decodedText = removeEncoding("Ich hei&szlig;e David");
console.log(decodedText);

Друкує: Ich Heiße David

PS на це знадобилося півтори години.


0

Щоб не скасувати HTML-суті * в JavaScript, ви можете використовувати невелику бібліотеку html-escape :npm install html-escaper

import {unescape} from 'html-escaper';

unescape('escaped string');

Або unescapeвиконувати функцію від Lodash або Underscore , якщо ви її використовуєте.


*) Будь ласка , зверніть увагу , що ці функції не охоплюють всіх HTML сутностей, але тільки найпоширеніші з них, тобто &, <, >, ', ". Для того, щоб все HTML екранування в суті ви можете використовувати він бібліотеку.


-1

Я використовую це у своєму проекті: натхненний іншими відповідями, але з додатковим захищеним параметром, може бути корисним при роботі з оформленими символами

var decodeEntities=(function(){

    var el=document.createElement('div');
    return function(str, safeEscape){

        if(str && typeof str === 'string'){

            str=str.replace(/\</g, '&lt;');

            el.innerHTML=str;
            if(el.innerText){

                str=el.innerText;
                el.innerText='';
            }
            else if(el.textContent){

                str=el.textContent;
                el.textContent='';
            }

            if(safeEscape)
                str=str.replace(/\</g, '&lt;');
        }
        return str;
    }
})();

І це корисно як:

var label='safe <b> character &eacute;ntity</b>';
var safehtml='<div title="'+decodeEntities(label)+'">'+decodeEntities(label, true)+'</div>';

-1

Усі інші відповіді тут мають проблеми.

Методи document.createElement ('div') (включаючи ті, що використовують jQuery) виконують будь-який JavaScript, переданий у нього (проблема безпеки), а метод DOMParser.parseFromString () обробляє пробіл. Ось чисте рішення JavaScript, яке не має жодної проблеми:

function htmlDecode(html) {
    var textarea = document.createElement("textarea");
    html= html.replace(/\r/g, String.fromCharCode(0xe000)); // Replace "\r" with reserved unicode character.
    textarea.innerHTML = html;
    var result = textarea.value;
    return result.replace(new RegExp(String.fromCharCode(0xe000), 'g'), '\r');
}

TextArea використовується спеціально для уникнення виконавчого коду js. Це передає:

htmlDecode('&lt;&amp;&nbsp;&gt;'); // returns "<& >" with non-breaking space.
htmlDecode('  '); // returns "  "
htmlDecode('<img src="dummy" onerror="alert(\'xss\')">'); // Does not execute alert()
htmlDecode('\r\n') // returns "\r\n", doesn't lose the \r like other solutions.

1
Ні, використання іншого тегу не вирішує проблему. Це все-таки вразливість XSS, спробуйте htmlDecode("</textarea><img src=x onerror=alert(1)>"). Ви розмістили це після того, як я вже вказав на це питання у відповіді Серхіо Белевського.
Володимир Палант

Я не можу відтворити описане вами питання. Я маю ваш код у цій JsFiddle, і під час запуску не з’являється попередження. jsfiddle.net/edsjt15g/1 Ви можете подивитися? Який браузер ви використовуєте?
EricP

2
Я використовую Firefox. Chrome справді обробляє цей сценарій по-різному, тому код не виконується - не те, на що слід покладатися.
Володимир Палант

-1
var encodedStr = 'hello &amp; world';

var parser = new DOMParser;
var dom = parser.parseFromString(
    '<!doctype html><body>' + encodedStr,
    'text/html');
var decodedString = dom.body.textContent;

console.log(decodedString);

@Wladimir Palant (автор AdBlock Plus) вже дав відповідь DOMParser на 4 роки раніше. Чи читали ви попередні відповіді, перш ніж публікувати свої?
Дан Даскалеску

-7

Існує варіант, який на 80% такий же продуктивний, як відповіді на самому верху.

Дивіться орієнтир: https://jsperf.com/decode-html12345678/1

тест на продуктивність

console.log(decodeEntities('test: &gt'));

function decodeEntities(str) {
  // this prevents any overhead from creating the object each time
  const el = decodeEntities.element || document.createElement('textarea')

  // strip script/html tags
  el.innerHTML = str
    .replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '')
    .replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '');

  return el.value;
}

Якщо вам потрібно залишити теги, то видаліть два .replace(...)виклики (ви можете залишити перший, якщо сценарії не потрібні).


6
Вітаємо, вам вдалося приховати вразливість за допомогою неправдивої логіки санітазії, все для виграшу в виконанні, яке не має значення на практиці. Спробуйте зателефонувати decodeEntities("</textarea '><img src=x onerror=alert(1) \">")у Firefox. Будь ласка, припиніть намагатися очистити HTML-код регулярними виразами.
Володимир Палант
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.