我正在调查防御各种类型的攻击,我找到了一个我不太了解的。
我有以下html:
<body onload="foo(''/alert(/Gotcha/)/'');">
<script>
function foo(){
alert("Inside Foo");
}
</script>
</body>
</html>
如果你运行它,你会看到一条警告,上面写着“/ Gotcha /”,后面跟着一个说“Inside Foo”的警告。
发生了什么事?为什么参数中的警报(foo甚至没有)正在运行?
更重要的是,如果我在参数中删除任何斜杠或单引号,它就不起作用。
如果我将其更改为
<body onload="foo('/alert(/Gotcha/)/');">
我得到的只是“Inside Foo”。
如果我将其更改为
<body onload="foo('/alert(Gotcha)/');">
或删除任何/ s我什么都没得到。
'和/是什么让它起作用?
答案 0 :(得分:3)
我们有一个复杂的表达,所以让我们分解它:
foo(''/alert(/Gotcha/)/'');
foo
的调用,''/alert(/Gotcha/)/''
作为参数(JS中的函数没有硬参数,您可以发送尽可能多的函数,甚至如果函数声明没有指定它们)''
,后跟分割字符/
,后跟alert
函数,然后是另一个分区和另一个空字符串alert
以评估foo
的参数,并且整个参数表达式的结果为NaN
,因为字符串不是{\ n}由于函数foo
不使用它而无法实现可分割foo
。答案 1 :(得分:0)
foo
调用中的参数运行的原因是因为它被解释为JavaScript。您在foo(''/alert(/Gotcha/)/''
中传递的参数基本上是2个字符串,在它们的中间是alert
调用。
答案 2 :(得分:0)
函数参数在函数被调用之前都被评估。所以当你写:
foo(alert('/Gotcha/'));
首先评估alert('/Gotcha/')
,这会导致/Gotcha/
显示。然后,alert()
的返回值作为参数传递给foo()
。 foo()
忽略了它的参数,但这对第一步来说并不重要。
将其更改为
时foo('/alert(/Gotcha/)/');
那么参数是文字字符串,而不是函数调用。因此评估它只返回字符串内容,它不会调用alert()
函数。
我看不出任何理由
<body onload="foo('/alert(Gotcha)/');">
与
的行为有所不同<body onload="foo('/alert(/Gotcha/)/');">
所以我怀疑你的实际代码有一个拼写错误,你没有在这里复制。检查您的Javascript控制台是否有语法错误消息。
答案 3 :(得分:0)
问: “参数中嵌入的Javascript函数会自动运行吗?”
答:它与函数参数无关。 foo 函数可以简单地添加已经混淆的表达式的混淆。这是编写等效的简单方法:
onload="alert(/Gotcha/)"
想要提醒/ Gotcha / regex文字的内容。
正文onload赋值字符串中提供的正则表达式文字只是在同一个字符串中提供的警报函数的被动值,并且没有分享正在进行的内容。
其他所有内容都只是掩盖简单分配的一种聪明方式,例如上面给出的onload="alert(/Gotcha/)"
代码行。
唯一能让它发挥作用的是内联事件分配是需要进行评估以便执行的字符串。
因此eval( ''/alert(/Gotcha/)/'' )
也会这样做。或者将其全部恢复原状:eval( "foo(''/alert(/Gotcha/)/'');" )
。
所以是的,可以执行内联分配给元素事件的任何类型的字符串内容。但是,setTimeout("foo(''/alert(/Gotcha/)/'');", 1000)
能够做同样的事情也是如此。
所以,“不”它与函数参数无关,而是将字符串内容解析为文档正文元素的内联事件。
<强> 编辑: 强>
对包含图像html的字符串的内联JavaScript是(出于上面解释为什么Gotcha警报有效的原因)最危险的代码注入而无需用户输入。这是因为图像元素可以处理 onerror 事件,任何任意代码块都可以执行,如:
<img
src="http://Idontexist.com/wrongfolder/missingimage.jpg"
onerror="your arbitrary, but well written (malicious) code here!"
>