嵌入参数中的Javascript函数是否自动运行?
我正在调查防御各种类型的攻击,我发现了一种我不太了解的攻击 我有以下html:嵌入参数中的Javascript函数是否自动运行?,javascript,xss,Javascript,Xss,我正在调查防御各种类型的攻击,我发现了一种我不太了解的攻击 我有以下html: <body onload="foo(''/alert(/Gotcha/)/'');"> <script> function foo(){ alert("Inside Foo"); } </script> </body> </html> 函数foo(){ 警惕(“内富”); } 如果你运行这个程序,你会看到一个警告,上面写着“/G
<body onload="foo(''/alert(/Gotcha/)/'');">
<script>
function foo(){
alert("Inside Foo");
}
</script>
</body>
</html>
函数foo(){
警惕(“内富”);
}
如果你运行这个程序,你会看到一个警告,上面写着“/Gotcha/”,后面紧接着一个警告,上面写着“Inside Foo”
发生什么事了?为什么参数(foo甚至没有)中的警报正在运行
更重要的是,如果我删除参数中的任何斜杠或单引号,它就不起作用
如果我把它改成
<body onload="foo('/alert(/Gotcha/)/');">
<body onload="foo('/alert(Gotcha)/');">
我得到的只是“内福”
如果我把它改成
<body onload="foo('/alert(/Gotcha/)/');">
<body onload="foo('/alert(Gotcha)/');">
或者移除任何我没有得到任何东西的/s
'和/的作用是什么?调用运行
foo
中的参数是因为它被解释为JavaScript。您在foo(alert('/Gotcha/'));
它首先计算alert('/Gotcha/')
,这会导致显示/Gotcha/
。然后alert()
的返回值作为参数传递给foo()
foo()
忽略其参数,但这对于第一步并不重要
当你把它改成
foo('/alert(/Gotcha/)/');
然后参数是一个文本字符串,而不是函数调用。因此,对其求值只返回字符串内容,而不调用alert()
函数
我看不出有什么原因
<body onload="foo('/alert(Gotcha)/');">
会有任何不同的表现
<body onload="foo('/alert(/Gotcha/)/');">
因此,我怀疑您的实际代码中有一个您没有复制到此处的输入错误。请检查您的Javascript控制台中的语法错误消息。我们在那里有一个复杂的表达式,因此让我们将其分解:
foo(“”/alert(/Gotcha/)/“”);
foo
,并将'/alert(/Gotcha/)/'
作为参数(JS中的函数没有硬参数,您可以发送任意数量的参数,即使函数声明没有指定它们)'
,后跟除法字符/
,后跟警报
函数,然后是另一个除法和另一个空字符串alert
使用正则表达式的字符串表示来执行,以计算foo
的参数,整个参数表达式的结果是NaN
,因为字符串是不可分割的,这并不重要,因为函数foo
没有使用它foo
Q:“嵌入参数中的Javascript函数是否自动运行?”
A:它与函数参数无关。foo函数只是为了让已经模糊的表达式更加混乱。这只是一种复杂的编写等价物的方法:
onload="alert(/Gotcha/)"
它想提醒/Gotcha/regex literal的内容
body onload赋值的字符串中提供的regex文本只是在同一字符串中提供的警报函数的被动值,与那里发生的事情没有任何关系
其他一切都只是掩盖简单赋值的一种聪明方法,比如上面给出的onload=“alert(/Gotcha/)”
代码行
唯一能让它起作用的是,内联事件分配是需要计算才能执行的字符串。
因此,eval(“”/alert(/Gotcha/)/“”)
也会这样做。或者将其全部恢复为原始形式:eval(“foo(“”/alert(/Gotcha/)/“”);”
)
因此,是的,可以执行内联分配给元素事件的任何类型的字符串内容。但是,setTimeout(“foo(“”/alert(/Gotcha/)/“”);”,1000)
也可以执行完全相同的操作
因此,“no”与函数参数无关,而是与将字符串内容解析为文档体元素的内联事件有关
编辑: 包含图像html的字符串上的内联JavaScript(出于上文解释的Gotcha警报工作原理)是最危险的代码注入,无需用户输入。这是因为图像元素可以处理OneError事件,可以对其执行任意代码块,如:
<img
src="http://Idontexist.com/wrongfolder/missingimage.jpg"
onerror="your arbitrary, but well written (malicious) code here!"
>
如果没有逗号分隔多个参数,它是如何传递的?@dandavis第二个警报
?很高兴意识到斜杠在做除法,我完全忽略了这一点。但实际上,字符串是可除的,因为它首先将它们转换为数字。然而,空字符串转换为数字0
,并且0/0
是NaN
@Barmar谢谢。至于除法,是的,0/0
给出NaN
,但在这种情况下,这不是给出NaN
的部分。警报的结果是未定义的
,因此这是首先给出NaN
的部分,即0/undefined/0
,bu这是吹毛求疵。我没有在我的回答中讨论它,因为它与问题没有直接关系,因为没有使用该参数,但是,是的,很好的一点是,我可以解释为什么它是NaN
。这非常有帮助,谢谢。但接下来的问题是:为什么“onload=foo(alert(/Gotcha/);”有效,但“onload=foo(alert(Gotcha))失败?这是怎么回事