由于 XSS 漏洞,如何将此 innerhtml 循环转换为内部文本?

Posted

技术标签:

【中文标题】由于 XSS 漏洞,如何将此 innerhtml 循环转换为内部文本?【英文标题】:How can I convert this innerhtml loop to a innertext one because XSS vulnerabilities? 【发布时间】:2020-03-16 02:42:03 【问题描述】:

我需要将此循环转换为带有动态添加内容的内部文本,我该怎么做我在互联网上查看但找不到任何内容?

function showMessages(messages) 

    jsonMessages.innerhtml = "<tr><th>Naam</th><th>Bericht</th><th>Datum</th></tr>";

        messages.sort(function (a, b) 
            return a.created_at > b.created_at ? 1 : -1;
        );
        for (var i = 0; i < messages.length; i++) 
            jsonMessages.innerHTML +=  `<tr><td>$messages[i].user_id</td><td>$messages[i].content.replace(/</g,"&lt;")</td><td>$messages[i].created_at</td></tr>`;
        
    console.log(messages);

【问题讨论】:

.innerHTML 更改为.innerText?请注意,尽管这样做会使 html 不会呈现为 html 元素,但您只会显示一个 html 字符串。你确定要改成innerText吗? 不支持动态添加的 在什么情况下不起作用? 因为它不是像元素一样渲染,而是像文本一样 只需单独创建元素并使用innertext添加文本。这需要时间......不要偷懒 【参考方案1】:

要更改代码以通过使用innerText 而不是将innerHTML 任意设置为某些未知代码来防止xss,您需要先自己创建元素,然后设置其内容

例如

//create a tr element
tr = document.createElement('tr');
//create new cell for above tr
td = tr.insertCell();
td.innerText = messages[i].user_id;

您可以对所有具有动态内容的元素执行此操作。因此,在您的情况下,您可以执行以下操作

for (var i = 0; i < messages.length; i++) 
  let tr = document.createElement('tr');
  let userIdCell = tr.insertCell();
  let contentCell = tr.insertCell();
  let dateCell = tr.insertCell();
  userIdCell.innerText = messages[i].user_id;
  contentCell = messages[i].content;
  dateCell = messages[i].created_at;

  //finally add it to your table
  jsonMessages.appendChild(tr);
 

还有其他路由可以做同样的事情,比如将一个空白字符串的 html 结构放入一个元素中,然后选择元素并设置它们:

let tr = document.createElement('tr');
tr.innerHTML = `<tr><td></td><td></td><td></td></tr>`;
//first td child
tr.children[0] = messages[i].user_id;
//second td child
tr.children[1] = messages[i].content;
//third td child
tr.children[2] = messages[i].created_id;

这完全取决于您的个人喜好。重点是先创建元素,然后设置它们的 innerText 属性,而不是将整个 html 设置为一个。

【讨论】:

【参考方案2】:
function showMessages(messages) 

    jsonMessages.innerHTML = "<tr><th>Naam</th><th>Bericht</th><th>Datum</th></tr>";

        messages.sort(function (a, b) 
            return a.created_at > b.created_at ? 1 : -1;
        );

        for (var i = 0; i < messages.length; i++) 

           var mainTr = document.createElement('tr');
           var td1 = document.createElement('td').appendChild(document.createTextNode(messages[i].user_id));
           var td2 = document.createElement('td').appendChild(document.createTextNode(messages[i].content.replace(/</g,"&lt;")));;
           var td3 = document.createElement('td').appendChild(document.createTextNode(messages[i].created_at));

           mainTr.appendChild(td1);
           mainTr.appendChild(td2);
           mainTr.appendChild(td3);

           jsonMessages.appendChild(mainTr);

        
    console.log(messages);

【讨论】:

appendChild 返回附加的子元素而不是原始元素。因此,您的调用将 td1,td2,td3 设置为相应的文本节点,而不是 &lt;td&gt; 元素。

以上是关于由于 XSS 漏洞,如何将此 innerhtml 循环转换为内部文本?的主要内容,如果未能解决你的问题,请参考以下文章

Web 安全漏洞之 XSS 攻击

雅虎邮箱存储型XSS漏洞,黑客能看任何人的邮件

Web 安全漏洞之 XSS 攻击

发现XSS漏洞的一般做法都有哪些?

转载 | Web 安全漏洞之 XSS 攻击

我是如何黑盒测试XSS漏洞的?