面试的时候被问到这样一个问题,为什么新版Chrome取消了XSS Audit机制?
以前看到过文章说新版Chrome取消这个的原因是因为被绕过的姿势过多(我也不知道几个)或者说是误报影响到正常功能了。并说用trusted-types
的API替换XSS Audit
能彻底杜绝DOM XSS
。
仔细跟了一下谷歌的开发文档介绍,通过给CSP配置一个trusted-types
属性:
Content-Security-Policy: trusted-types *
本地测试79.0版本:
<?php header("Content-Security-Policy: trusted-types *"); $a= <<<EOF <html> <head> </head> <body> </body> <script> const templateId = location.hash.match(/tplid=([^;&]*)/)[1]; // typeof templateId == "string" document.head.innerHTML += decodeURI(templateId) // Throws a TypeError. </script> </html> EOF; echo $a;
但是并没有抛出错误,继续翻了下文档,找到问题所在:
需要用Chrome73-78的版本,其次默认配置是不开的,访问chrome://flags/#enable-experimental-web-platform-features
将其配置打开。
这里用Chrome78测试:
抛出一个错误,强制要求我们使用TrustedHTML
,修改代码:
<?php header("Content-Security-Policy: trusted-types *"); $a= <<<EOF <html> <head> </head> <body> </body> <script> const templatePolicy = TrustedTypes.createPolicy('template', { createHTML: (templateId) => { const tpl = templateId; if (/^[0-9a-z-]$/.test(tpl)) { return `<link rel="stylesheet" href="./templates/${tpl}/style.css">`; } throw new TypeError(); } }); const html = templatePolicy.createHTML(location.hash.match(/tplid=([^;&]*)/)[1]); // html instanceof TrustedHTML document.head.innerHTML = html; </script> </html> EOF; echo $a;
通过TrustedTypes.createPolicy
自定义过滤后,return一个TrustedHTML
来满足CSP的可信要求:
在Chrome79下,即使我们开启了Experimental Web Platform features
这个配置,仍然会遇到TrustedTypes is not defined
的问题,emm可能功能正在试验中,然后新版又给移除了?
其次因为这个问题测试的时候,Chrome会默认更新到79版本有点烦,去这里,找了个78版本的下载,接着输msconfig
把谷歌服务的更新关了即可
最后打开Chrome效果是这样的:
最后简单总结一下,Chrome取消了XSS Auditor,取而代之的是trusted-types
可信API,声称可以彻底杜绝DOM XSS,经过一番体验后,其实本质上为强制开发写一段更为严格的过滤规则。