【问题标题】:prevent Xss using encoding, but user readability is so poor防止Xss使用编码,但用户可读性太差
【发布时间】:2026-01-28 16:45:01
【问题描述】:

为了保护 xss 攻击,我尝试使用以下函数对要显示给用户的每条消息进行编码。

function encodeRFC5987ValueChars(str) 
{
    return encodeURIComponent(str).
        // Note that although RFC3986 reserves "!", RFC5987 does not,
        // so we do not need to escape it
        replace(/['()]/g, escape). // i.e., %27 %28 %29
        replace(/\*/g, '%2A').
            // The following are not required for percent-encoding per RFC5987, 
            // so we can allow for a little better readability over the wire: |`^
            replace(/%(?:7C|60|5E)/g, unescape);
}

示例输入消息如下所示

Start 20 TV's test; star ;; '' -- testagain., comma. </>

我从这个函数收到的输出消息如下所示。

Start%2020%20TV%27s%20test%3B%20star%20%3B%3B%20%27%27%20--%20testagain.%2C%20comma.%20%3C%2F%3E

我尝试显示如下。

 document.getElementById("labelResult").innerHTML = "Start%2020%20TV%27s%20test%3B%20star%20%3B%3B%20%27%27%20--%20testagain.%2C%20comma.%20%3C%2F%3E";

一切正常,但用户可读性非常差。
我需要解码吗?如果我解码了,那我怕会导致xss攻击?

请有任何建议。

【问题讨论】:

  • 我不会使用encodeURIComponent 来转义字符串,它会替换的东西的数量是超级大材小用。看看这个问题/答案:*.com/questions/6234773/…

标签: javascript xss decode encode


【解决方案1】:

您将数据插入 HTML,而不是 URL。

要防御 XSS,您需要为 HTML 正确编码。 encodeURIComponent 不应该在这附近。

var textNode = document.createTextNode("Start 20 TV's test; star ;; '' -- testagain., comma. </>");
document.getElementById("labelResult").innerHTML = ""; // Erase existing content
document.getElementById("labelResult").appendChild(textNode);

可能有一个 XSS 向量,无论您使用什么方法将 Start 20 TV's test; star ;; '' -- testagain., comma. &lt;/&gt; 作为用户输入并将其放入 JavaScript 中……但您还没有向我们展示您是如何做到的。

【讨论】:

  • 假设用户键入了必须保存在我的数据库中的消息。在保存到数据库之前,我对其进行了编码并将其保存到数据库中。当用户想要查看数据时,我必须检索并显示给用户。谢谢。
  • 在将其放入数据库之前不要对其进行编码(以防止 SQL 注入使用准备好的语句和绑定变量)。在将其放入页面之前如何对其进行编码取决于您将其从数据库中取出并放入页面的方法。页面加载时将其放入 HTML 属性中?在页面加载的脚本元素中生成原始 JavaScript?稍后使用 XMLHttpRequest 获取它并将其作为纯文本返回?三种不同的技术来解决它,以及三种不同的技术来防御 SQL 注入。