使用带有不受信任字符串的模板文字设置属性值时,是否存在 XSS 风险?

Is there XSS risk when using a template literal with an untrusted string to set an attribute value?

我正在构建一个 iframe,不是使用 innerHTML,而是使用 createElement。我使用了两个不受信任的字符串:

iframeEl.title = untrustedStr1;
iframeEl.src = `http://example.com/?id=${untrustedStr2}`;

根据 OWASP XSS 备忘单,title 属性是 totally safe,所以我对此并不担心。

但是,对于 iframeEl.src 的情况,我不是 100% 确定。

我正在考虑通常需要编码的 5 significant characters<>&"' 而且我看不出有任何方法可以逃脱模板文字。而且我也没有看到将 untrustedStr2 运行 作为 JavaScript 的机制。 (例如,如果 untrustedStr2 = 'document.cookie',它被插入为一个字符串,而不是通过计算)。

我想如果 untrustedStr2 是某种 getter 方法,我可能会遇到问题。但如果它绝对是一个字符串,这是安全的,我不需要编码,即使是 5 个重要字符。是吗?

使用 DOM 时,any 元素属性中没有 html 编码 问题。字符<>&"'不需要转义。

但是,您仍然需要处理各个属性的语义。虽然 title 只是一个普通字符串,除了显示工具提示外不用于任何其他用途,但其他字符串并不安全:

  • on… 事件处理程序包含 javascript 代码。无论如何,为它们分配字符串是一种不好的做法,但如果这样做,插值必须遵循 javascript 转义规则。
    Rule #3
  • style 属性包含 CSS 需要自己转义的规则。
    Rule #4
  • srchref 属性是浏览器将在某个时刻加载的 url。这些绝对是敏感的,当将值插入 url 时,您需要遵循 URL 编码规则。
    Rule #5
  • (并非详尽无遗)

在您的特定情况下,如果您无法对 url 进行编码 untrustedStr2,攻击者可能会向 example.com 发送任意查询参数或片段。如果 example.com 不易受到反射 XSS 的影响(攻击者可能会通过其他渠道向用户发送相同的 link),这本身不是安全问题,但它是损坏的功能(不良行为) ,但它仍然是您的页面认可 linked 内容。

因此,如果 untrustedStr2id URI 查询参数的值,您绝对应该使用

iframeEl.src = `http://example.com/?id=${encodeURIComponent(untrustedStr2)}`;
//                                       ^^^^^^^^^^^^^^^^^^

untrustedStr2 似乎不太可能评估 and/or 从字符串中跳出。但是,如果您不对其进行编码,您可能会允许“HTTP 参数污染 (HPP)”。

// untrustedStr2 = '9&id=42';
iframeEl.src = `http://example.com/?id=${untrustedStr2}`;

By itself, this is not necessarily an indication of vulnerability. However, if the developer is not aware of the problem, the presence of duplicated parameters may produce an anomalous behavior in the application that can be potentially exploited by an attacker. As often in security, unexpected behaviors are a usual source of weaknesses that could lead to HTTP Parameter Pollution attacks in this case.

https://owasp.org/www-project-web-security-testing-guide/v41/4-Web_Application_Security_Testing/07-Input_Validation_Testing/04-Testing_for_HTTP_Parameter_Pollution.html

或者您可以允许 CSRF 攻击尝试:

// untrustedStr2 = '9&action=delete';
iframeEl.src = `http://example.com/?id=${untrustedStr2}`;

我认为编码会更安全。