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

3.1k Views Asked by At

I'm building an iframe, not with innerHTML, but with createElement.. I have two untrusted strings that are used:

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

According to the OWASP XSS cheatsheet, the title attribute is totally safe, so I'm not worried about that.

However, I'm not 100% sure about the iframeEl.src case.

I'm thinking about the 5 significant characters that typically need to be encoded: <, >, &, ", and ' and I don't see any way to escape out of the template literal. And I also don't see a mechanism to have untrustedStr2 run as JavaScript. (For example, if untrustedStr2 = 'document.cookie', it's interpolated as a string, not via evaluation).

I suppose if untrustedStr2 is a getter method somehow, I could have a problem. But if it's absolutely a string, this is safe and I don't need to encode, not even for the 5 significant characters. Is that right?

2

There are 2 best solutions below

0
On BEST ANSWER

When working with the DOM, there are no html encoding issues in any element properties. The characters <, >, &, ", and ' do not need escaping.

However, you still need to deal with the semantics of the respective attribute. While title is just a plain string that's not used for anything but displaying tooltips, others are not safe:

  • on… event handlers contain javascript code. It's a bad practice to assign strings to them anyway, but if you do, interpolating values must follow javascript escaping rules.
    Rule #3
  • style properties contain CSS rules which need their own escaping.
    Rule #4
  • src or href attributes are urls that the browser will load at some point. Those definitely are sensitive, and when interpolating values into urls you need to follow URL encoding rules.
    Rule #5
  • (not meant to be exhaustive)

In your particular case, if you fail to url-encode the untrustedStr2, the attacker may send arbitrary query parameters or fragments to example.com. This is not a security issue in itself if example.com isn't susceptible to reflected XSS (the attacker may send the same link to the user via other channels), but it is broken functionality (undesired behaviour), but still it's your page endorsing the linked content.

So if untrustedStr2 is meant as a value of the id URI query parameter, you should definitely use

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

It seems unlikely for untrustedStr2 to evaluate and/or break out of the string. However if you don't encode it you may allow "HTTP Parameter Pollution (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.

See 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

Or you could allow an attempt at a CSRF attack:

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

I think it would be safer to encode it.