0

I need to allow a user to pass unsafe text into an iframe URL:

<iframe src="https://example.com?foo=INPUT"></iframe>

Inside the iFrame render code, I have this:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title></title>
</head>
<body>
  <script>
    window.myVar = '<%= cleaned %>';
  </script>
</body>
</html>

I'm using ruby, but that's not specific to the question.

The important parts are:

  1. I am explicitly defining the ' single quotes within the iFrame HTML myself. The ERB <%= %> execution context is within the quotes.

  2. The only cleaning I am doing in ruby is the following regex:

    cleaned = value.gsub(/[`'"\\]+/, '')
    

I realize having double quotes and backticks in there is also not needed, but I wanted that false feeling of extra comfort 👹. With that said, obviously backticks in iFrame HTML instead of single quotes would require extra escaping to prevent interpolation, but I will never use backticks in the iFrame HTML. It would either be single or double quotes only.

Is this safe from XSS? I added \ to the regex so they can't escape the last quote, breaking the JS.

1 Answer 1

2

Is the iframe embedded on your own page, or on third-party pages? If it's on your own page, you need some filtering on that src URL too.

Regardless, this is probably technically safe enough (though the <> are absolutely necessary). It's a very dangerous pattern - putting user input directly into a script block at all, especially with nothing but a short block list for sanitization - but you have filtered out everything that is definitely harmful today. However, your filter is assuming that the JS spec doesn't change (like it did when backtick became a metacharacter) and that the HTML spec is similarly static (the reason <> is dangerous is because you can actually terminate an HTML scribt block from within a JS string and then start a new one). Mind you, if you want to prevent somebody from breaking the code (even though it won't get them XSS), you need to filter out newlines and some other control characters too, as those will prematurely break the string, causing a syntax error.

(There's also the thing where that filter will turn the string I <3 "Bob's Burgers"! into I 3 Bobs Burgers! but maybe you don't care. If you have any sort of strict idea what the input should look like, though, you should be validating to that in particular.)

While I see that you're using UTF-8 and therefore can handle arbitrary characters, you should make sure your server knows this. Some servers will automatically convert multibyte characters to their "closest" ASCII (or at least single-byte code page) representation before emitting them, which means your filter might miss some character that resembles (but is not technically) an apostrophe/single-quote, and then the server goes and helpfully converts it for you. That's a relatively rare problem, but definitely one to test.

3
  • Very interesting, I absolutely didnt know that about terminating from within a script but that makes total sense. The iFrame URL will always reference our own server (in this case example.com is our server). Can you explain what you mean about the further filtering?
    – Tallboy
    Commented Mar 19, 2022 at 21:03
  • I asked where the iframe was hosted from / embedded in, not what it was embedding; if your own pages are hosting the iframe (rather than only hosted by it), then you need to escape or validate the INPUT in the URL. If that's just user input then the user could potentially break out of the HTML attribute and introduce XSS there too. However, if the iframe is only for other people to host your content, then the security of the hosting page is probably not your concern.
    – CBHacking
    Commented Mar 20, 2022 at 2:18
  • Got it, yes they're hosting the iframe on their own domain/website. Thanks for the info!
    – Tallboy
    Commented Mar 20, 2022 at 2:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .