作者:卢峰(清锐)
本文简要介绍了 Script Error 问题的前因后果,但也不局限于 Script Error,对于通用的系统性问题,应该找到系统性解决方案,进而治本治标。
Script Error 起因与以后解法
受浏览器同源策略限度,未知跨域脚本执行谬误时,抛出的错误信息为 “Script error.”,导致开发者无奈定位具体谬误。为了获取具体错误信息及堆栈,个别解法是给 Script 标签配置 crossorigin 属性,同时对应脚本服务端需配置 Access-Control-Allow-Origin 响应头。
另外还有一些 hack 解法,对浏览器原生 API 做代理,将业务代码放在 Try Catch 作用域中执行,但写好代理办法是不容易的,粗制滥造的代理办法会制作很多暗藏 Bug,并且大量 Try Catch 在一些 JS Engine 中也存在额定性能损耗,为了解决 Script Error 采纳此计划得失相当。
还有什么问题
- crossorigin 不好加
异步加载脚本套娃,A 加载 B,B 加载 C,以至于不晓得加载了哪些内部脚本
须要服务端配合设置响应头 Access-Control-Allow-Origin
- crossorigin 加不了
内部注入代码,如浏览器插件、定制 Webview 容器(xx 浏览器)
- 有效 Script Error 数据,难以评估对业务理论影响,并且消耗监控资源
溯源:为什么是 Script Error
从 2006 年一篇安全漏洞文章说起:I know if you’re logged-in, anywhere
在那个年代大量网站都是服务端渲染,服务端依据用户登录态返回不同页面内容,黑客通过 Script 加载指标站点,用户已登录、未登录返回的 Response 内容不同,报错信息也会有差别,这样就能够通过报错信息辨别用户是否登录,进一步开展针对性的攻打。
<script src=”http://mail.google.com/mail/”></script>
已登录:
未登录:
对于其余站点也是相似,错误信息中总会有差别,比方亚马逊登录和未登录,报错的 LineNo 不同。
基于此,WHATWG 对错误信息透出制订了标准:
Chrome 实现:
《I know if you’re logged-in, anywhere》地址:https://blog.jeremiahgrossman…
Script Error 标准是否能调整
通过以上信息,咱们能够了解 Script Error 的设计初衷以及其合理性,但我也有疑难,在明天浏览器同源策略比较完善的状况下,是否有必要屏蔽所有信息(error message、lineno、colno、url)?是否将产生 Script Error 的脚本 url 裸露进去,以便开发者收集到错误信息时疾速定位谬误起源,这样也不便评估影响面,比方显著是注入的脚本谬误,间接疏忽即可。
翻阅 WHATWG Github 历史 issue,发现曾经有过相干探讨,很明确答案是 No,大略起因是以后的同源策略曾经很全面(简单),不想在挖坑。以至于对 unhanlderejection,连 Script Error 都不违心报。
相干探讨地址:https://github.com/whatwg/htm…
unhanlderejection 地址:https://github.com/whatwg/htm…
其余大厂如何解决 Script Error
我在几个大厂网站上做了测试,加载一个第三方脚本,第三方脚本肯定会报错,看看对应站点如何解决。
var s = document.createElement('script');
s.src = 'https://g.alicdn.com/dinamic/h5-tb-cart/5.0.41/index.min.js';
document.body.appendChild(s);
- Google:惯例解决,间接上报 Script Error
- Twitter: 通过 CSP 策略拦挡了未知脚本加载,包含 Github、FaceBook 都采纳相似计划
- QQ 视频:除了上报 Script Error,并监控上报异步加载的脚本
面向未来咱们应该如何解决 Script Error
面向未来看问题,咱们不能与规范南辕北辙,同源策略是以后解决 Web 平安问题的重要伎俩,在将来只会更欠缺,咱们应该踊跃理解与利用。以后国内互联网对同源策略的理解与利用大多止步于 Access-Control-Allow-Origin: *,这是远远不够的。
因而,面向未来 Script Error 问题 Twitter 的解决形式绝对正当,只容许站点加载白名单脚本,对白名单脚本一一做 CrossOring 等配置,同时也杜绝了内部脚本注入。对于淘宝来说,受限于业务体量以及历史包袱,做这种革新难度可想而知,但咱们应该朝这个方向致力,而不是让开发者面对 Script Error 不知所措,靠猜想或是加谬误过滤解决问题。
回到当下,短期的解决方案要加强跨域脚本的感知能力,能够配置 CSP Report Only 上报跨域脚本,也能够通过原始伎俩统计,进而对相干脚本做跨域配置,对于显著的跨域脚本如埋点、唤端、以及平安系列脚本,短少 crossorigin 的尽快修复。
CSP Report Only 地址:https://developer.mozilla.org…
document.querySelectorAll('script[src]:not([crossorigin])')
本文简要介绍了 Script Error 问题的前因后果,但也不局限于 Script Error,对于通用的系统性问题,应该找到系统性解决方案,进而治本治标。
参考文档
- what is script error(地址:https://blog.sentry.io/2016/0…)
- Cryptic “Script Error.” reported in Javascript in Chrome and Firefox(地址:https://stackoverflow.com/que…)
- 解决 “Script Error” 的另类思路(地址:https://juejin.cn/post/684490…)
- iOS Privacy: Instagram and Facebook can track anything you do on any website in their in-app browser(地址:https://krausefx.com/blog/ios…)
- I know if you’re logged-in, anywhere(地址:https://blog.jeremiahgrossman…)
- HTML Spec: Runtime script errors(地址:https://html.spec.whatwg.org/…)
- “Script error.” message in window.onerror makes bad DevExp trade off(地址:https://github.com/whatwg/htm…)
- unhandledrejection should fire even for muted scripts(地址:https://github.com/whatwg/htm…)
- Content-Security-Policy-Report-Only(地址:https://developer.mozilla.org…)