经过近一个半Sprint的摸索和尝试,总算给项目(Portal)穿上了CSP这层安全盔甲,在这里忍不住要给各位吐槽下, 分享处理CSP问题过程中的经验。
什么是CSP ? CSP is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross-Site Scripting (XSS) and data injection attacks. These attacks are used for everything from data theft to site defacement or distribution of malware. -MDN 简而言之,CSP规范可以设定资源(javascript, css, image, frame ….)加载域的白名单, 也可以限制内联Javascript的执行,避免由于系统漏洞导致中间人利用脚本注入攻击系统。
Portal实现哪些CSP Requirements ?
目前根据CSP规范 Portal 完成了 1. 资源加载来源的检测 2. 重构代码消除所有内联Javascript
Portal资源加载规则是什么? 目前 Portal没有跨域资源加载的情况,所以设置为self 本域有效,具体可参考CSP level 2规范CSP evel 2规范 Content-Security-Policy: default-src ‘self’; img-src ‘self’ data:; style-src ‘self’ ‘unsafe-inline’; script-src ‘self’ ‘unsafe-eval’ ‘nonce-{random string}’; object-src ‘none’; child-src ‘none’
CSP如何检测内联Javascript是否合法? 根据CSP level2定义,在CSP规则里引入nonce,浏览器根据CSP规则进行检测,只有申明nonce并且值与Response Header里值相同才被视为合法。 除此之外HTML里的JS事件都被认为非法。
W如何在Portal消除内联JS? 首先根据CSP 规则增加nonce定义,修改所有含有内联JS JSP页面, 其次消除所有HTML JS事件 , 最后修改所有空链接实现。 如下写法是不合法的
1.无nonce申明1
2
3<script type="text/javascript">
…
</script>
2.HTML JS1
<input onclick="javascript: alert('test')">
3.空链接实现1
2<a href="javascript:;">
<a href="javascript:void(0)">
Portal 实现CSP过程遇到的问题有哪些?
1. 清理内联JS
根据规范要求,所有HTML事件通过JS 来绑定 ,而不要使用HTML事件属性,空链接要改成1
<a href="#">
形式,为了避免页面刷新还需要阻止默认事件行为的触发。
2.处理bypass CSP检测
Portal大部分页面加载通过ajax 方式jquery 的load方法实现,由于采用’unsafe-eval’规则,允许通过load执行HTML中javascript, 绕过目前CSP的检测,需要改写loadPage方法, 详细细节参考
测试Cases 1 JSP引入非本域javascript或 css, 浏览器阻止引用<%= _(‘root’) %>
Case2 假如Web.jsp被注入恶意脚本,浏览器阻止脚本执行
Case3 假如ajax加载页面被注入恶意脚本,程序能检测并阻止脚本执行
1 | /** |
随着安全标准和规范地不断完善,浏览器安全性也在不断改进,需要我们能够了解并且使用到项目中,实现的过程中往往也需要改变我们的编程习惯,摸索的过程是痛苦的但痛苦过后就是方向和未来。