之前做过 xss 过滤 用的 js-xss
之前测试也都是正常的
今天看到他的测试内容: < img/src=1 onerror='top.onerror=alert; throw 2'>
看到这个 “/” 好像明白了什么, 不过为什么这种也会被浏览器识别成 img 标签 很纳闷
然后去看 js-xss 的 issues 发现了好像一样的 https://github.com/leizongmin/js-xss/issues/283
这么久也没回复,而且 js-xss 好像是不是也不维护了
虽然用其中的 onIgnoreTag 在其中做了标签名中是否有 “/” 然后去掉 “/” 后再调用 xss 函数 但是不知道还有没有类似的问题出现;
想问一下有没有别的好用的 xss 过滤办法
1
jowan 2023-12-06 16:41:31 +08:00
现在的浏览器不是上古的 IE 很多编写的缺陷和 BUG 会被它们主动修复 比如你缺少关闭标签 或者属性值拼写错误 它们都是尽量去帮你修复 有时候在控制台会给你一些 warning 实在修复不了 会直接给你报错
|
3
InDom 2023-12-06 16:48:00 +08:00 1
如果你不是富文本的话,其实直接用 innerText 而非 innerHTML 就可以避免。
至于框架,也有框架也有类似的安全方法。从原理上就杜绝了这种问题的发生。 如果你真的有富文本的需求,那么我一般是这么做的 禁止 script 与 on[a-zA-Z] 的出现,或者把 script on 替换为 scr-ipt on-. 宁错杀,不放过。 |
4
Forviler OP @jowan 所以 ‘/’ 是在修复之列的, 我试了几个别的都不行,这种不同浏览器还有不同的修复方案了,希望没有别的了
|
5
tabris17 2023-12-06 16:49:44 +08:00
甚至不同浏览器对于不规范 HTML Tag 处理方式还不一样,扯得很。最好的办法就是保存时服务端做一次 html 解析,规范化后保存
|
7
Forviler OP @InDom 确实是需要富文本,不然 innerText 完全不会有这种问题; 干掉 on[a-zA-Z] 和 script 确实一劳永逸;这项目是个老项目了,不想动太多; 下个项目要这样搞一下
|
11
yumusb 2023-12-06 16:59:29 +08:00
XSS 粗暴一点的话。直接过滤掉 引号与尖号。
|
12
lneoi 2023-12-06 17:11:08 +08:00
|
14
zsh2517 2023-12-06 20:00:13 +08:00 2
@jowan 我印象好像确实有规范要求这么干的,把中文句号换成点继续访问,不是浏览器自作主张的本土化/兼容。
刚才问 GPT + 翻了一下 RFC ,RFC 3490 里面确实规定了好几种分隔符 > 当使用点作为标签分隔符时,必须将以下字符识别为点:U+002E (句号)、U+3002 (表意句号)、U+FF0E (全幅句号)、U+FF61 (半幅表意句号)。 英文文档: https://datatracker.ietf.org/doc/html/rfc3490#section-3.1 中文翻译: https://rfc2cn.com/rfc3490.html 3.1 部分 |
15
zjp 2023-12-06 20:04:47 +08:00 via Android 1
@jowan 请用 example.com
|
17
a632079 2023-12-06 20:57:45 +08:00
mark. 我现在项目用的都是 xss 0 0 ,图方便。看来得换了。感谢楼主预警。
|
18
BaiLinfeng 2023-12-06 22:12:19 +08:00
表示从来都没使用过啊
|
19
Puteulanus 2023-12-06 22:15:29 +08:00
本来记得有个新出的 HTML Sanitizer API ,看了下浏览器兼容,可以当它没有了。。
|
20
dawn009 2023-12-07 01:58:00 +08:00
浏览器对不合规范的写法做了太多妥协,不要信任。
可以用 javascript 写一个简易的 HTML parser ,自己控制解析哪些 tag 、怎样解析。 |
21
LeeReamond 2023-12-07 04:07:12 +08:00
非前端,好奇把 script on 替换为 scr-ipt on-这个方法能不能 100%防御所有 xss 。另外同时也好奇 OP 一楼写的那个漏洞是怎么解释执行的,/相当于没加?
|
22
INW017bzMfgkkYGn 2023-12-07 07:29:48 +08:00
@jowan #6 你这是用的全局代理呀,这域名被墙了的。
|
23
siweipancc 2023-12-07 08:40:47 +08:00 via iPhone
@jowan 哇塞,辣眼睛
|
26
Forviler OP @LeeReamond 加了 / 的话 js-xss 不会把这个 tag 识别为 img 识别出来的 tag 名是 img/src , 但是浏览器会自动把 / 替换成空格,从而被当作 img 执行
|
28
Granado 2023-12-07 14:49:50 +08:00
@Forviler #9 这种前端领域的问题,是不是可以做一层前端的网关统一处理后再给后端服务?这样自己团队内就可以闭环这个问题。
|
30
Forviler OP @Granado 前端网关处理是指什么,ajax 请求拦截器里 做参数处理? 没想过这样做,感觉不如在 使用 innerHTML 的时候做处理要简单
|
32
onice 2023-12-07 20:56:28 +08:00
防御 xss 最正确的方法是实体编码,而不是黑白名单过滤。
请参阅: https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html |
34
Forviler OP @onice 没看明白,转为实体编码 我只知道一些 < 转为 < 之类的 不知道如何实现预防的,英文的翻过来没看太懂,
发现了新的问题 document.getElementById('rf').innerHTML= `<img/src=1 >` ; edge 下会显示为文本 document.getElementById('rd').innerHTML = `<img/src=1 >`; edge 下显示为 标签 不过 v-html 都会显示为标签 我再研究研究实体编码 |
35
onice 2023-12-08 14:40:25 +08:00
@Forviler 是这样子。XSS 的本质,是浏览器解析了攻击者插入到页面中的 JS 代码,,而这些代码恰好是恶意的,例如窃取用户 cookie 。
通过实体编码,我们就可以让攻击者插入的 js 代码原样显示在浏览器中,浏览器会显示尖括号,但并不会解析这些 js 代码。当然,浏览器中显示的是尖括号,但在代码层面,已经被处理为<之类的编码了。 对于大部分前端框架,例如 Vue 和 React ,默认就对 xss 进行防护了。当然, 除非你使用 v-html ,而通过 v-html 渲染的值,用户可以控制。 对于 Java 后端来说,,防御 XSS 的方法也很简单,加一个过滤器即可。把从前端传过来的所有数据,进行判断,如果发现尖括号等敏感的字符,就进行编码,例如转为:< 转换后的数据就是安全的了,转换后方可入库。 XSS 漏洞主要是危害用户的安全,XSS 往往导致用户的登录凭证被窃取,并不危害网站服务器。 大多数时候,XSS 都被划分为低危漏洞。 我上面说得可能也不是很详细,要不你参考下白帽子讲 web 安全,第三章 XSS 的部分。 XSS 漏洞很容易理解,是属于 web 漏洞中比较简单的。 书籍链接为: 链接: https://pan.baidu.com/s/1cmMkJH2_9I16A9DODUt5tg?pwd=xwld 提取码:xwld |
36
onice 2023-12-08 14:51:32 +08:00
@Forviler
@onice 再补充下另一本书:web 安全深度剖析,,这本书篇幅短一些。条例比白帽子讲 web 安全清晰一些。建议优先看这本。 只看 XSS 章节即可。 链接: https://pan.baidu.com/s/16s19_V5p3V-bMjsLtZLZMg?pwd=mhxz 提取码:mhxz |
37
onice 2023-12-08 15:01:35 +08:00
@Forviler
针对你当前的场景: document.getElementById('rf').innerHTML= `<img/src=1 >` ; edge 下会显示为文本 document.getElementById('rd').innerHTML = `<img/src=1 >`; edge 下显示为 标签 假如攻击者的代码为:<img/src=1 >,,你在代码中转为<img/src=1 >后,这就是消毒的操作。浏览器页面中会显示<img/src=1 >,但其实浏览器把显示的<img/src=1 >当成<img/src=1 >处理。这么一来,浏览器就不会真的把这串代码当成 img 标签进行渲染了。这样既能够不破坏用户输入的数据,又能够保障代码的安全(不被解析成 js 代码)。 document.getElementById('rd').innerHTML = `<img/src=1 >`; edge 下显示为 标签 这个就是危险的。假如攻击者的攻击代码为:<img/src=1 onerror="alert(xss)">,,由于没有进行编码,这个代码会被当成 js 处理,,浏览器会加载图片,但由于 url 不存在,图片加载失败,触发 onerror 事件,执行 alert 弹窗代码。当然这里仅仅是测试,alert 并不具备危害。但是如果 alert 是窃取 cookie 的代码,这可就危险了。 |
38
Forviler OP @onice #37 听起来好像是实体编码是确保用户输入的不会被当作代码来进行解析 这个意思;
那么我使用富文本的时候是必须要将数据当作代码来进行解析的,所以是不能进行实体编码的操作的么,因为浏览器会把它当作文本来显示 |
40
onice 2023-12-09 09:29:20 +08:00
@Forviler 攻击者也是我们的用户之一,,只不过是不怀好意的用户。所以,我们可以把攻击者看成是正常用户。那么,用户输入的数据,我们肯定不能破坏。例如用户输入 abc ,我们不能为了安全把数据改成 bcd 。所以,实体编码是个好办法。用户输入的数据,关键点在于攻击者输入的数据包含恶意代码,所以用实体编码我们既能让用户输入的数据原样显示在浏览器中,又能让即使是包含了恶意代码的数据不被浏览器解析。
那么我使用富文本的时候是必须要将数据当作代码来进行解析的,所以是不能进行实体编码的操作的么,因为浏览器会把它当作文本来显示。 至于富文本,你说得对,的确是这样子。富文本的业务场景下,我们必须要让浏览器解析用户输入的数据。所以实体编码后,富文本的输入数据不被解析,代码就会原封不动的显示在浏览器中。用户的格式设置就会失效,例如文本背景,字体加粗,图片等。 富文本的场景下宜采用白名单的方式。只允许用户输入特定的 HTML 标签,对用户的输入的数据要严格限制。 |
41
NewYear 2023-12-12 03:17:03 +08:00
接着楼主的<img/src=>试了下其他的符号,还有好几个会修正的符号……
没有用的冷知识又增加了。 |