内容安全策略CSP(Content-Security-Policy),如何预防xss ?
发布于 作者:苏南大叔 来源:程序如此灵动~
本文中,苏南大叔和大家聊聊一个非常有意思网页前端安全的话题,叫做:内容安全策略CSP(Content-Security-Policy)。看起来字面是有些陌生对不,确实不常用。在以前的话题中,苏南大叔提过一个xss的概念,当时提出的一个应对策略叫做httponly。这篇文章中,就提出第二个应对策略:CSP。

本文测试环境:chrome@90.0.4430.212。本文就提出非常简单的概念,以科普为主。本文涉及的header头是:Content-Security-Policy,实践过程中,还有个X-Content-Security-Policy,那么X-是兼容ie浏览器的(此处省略500字)。
CSP如何预防xss?
前端的同学们,一定会非常惊讶,这网络安全咋扯到自己身上了?一般来说,这些不都是后端或者运维的事情么?其实,就CSP而言,前端代码还真是可以做些事情。Content-Security-Policy能做什么?
xss的全称是:Cross Site Scripting,意思是:跨站脚本攻击。具体的说的话,就是利用代码漏洞,在页面里面生成并执行特殊的script,来获得cookie等敏感信息的。而Content-Security-Policy可以做到,让页面内的某些script能执行,而某些代码不能执行。因此,它是可以禁用页面内联的script的。

苏南大叔认为:从前端角度利用Content-Security-Policy来预防xss这件事情来说,Content-Security-Policy是典型的“杀敌三百自毁三千”。因为这个策略就是:禁止执行页面内直接内嵌的script脚本,但是可以执行放在.js文件里面脚本。那么,为了禁止可能潜在的xss,那么,以后就都不能在网页里面随手写内联的script脚本了。
下面的内联式的代码,将不被执行:
<script>alert('苏南大叔');</script>
<button onclick="javascript:alert('xss')">测试</button>报错信息是:
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self'". 
但是下面的self类型的代码,将可以执行:
<script src='alert.js'></script>alert.js:
alert('苏南大叔');禁止的主要手段
本文主要讨论的是如何利用Content-Security-Policy禁止内联inline的脚本。所以,下面的代码是有局限性的。大家想清楚自己的主要目的,再来复制代码。
方案一,需要服务器端发出下面的header信息:
script-src 'self'
方案二,如果想让前端人员来完成这个事项的话,代码如下,放到head区域即可:
<meta http-equiv="Content-Security-Policy" content="script-src 'self'">
<meta http-equiv="X-Content-Security-Policy" content="script-src 'self'">除了script-src 'self'外,实际上的选项还有很多,但不在本文的讨论范畴内。允许执行inline的代码(伪需求)
如果允许执行混杂在html代码中的script的话,可能需要发出下面这样的header。
script-src 'self' 'unsafe-inline'允许执行self和unsafe-inline两种类型的script。说实话,把inline的脚本污名化为unsafe-inline。这个操作不能说太酷炫。

<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
<meta http-equiv="X-Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">其实不写这个header代码就行了嘛。默认就是任何的script都可以执行的。您说是不?
相关链接
总结
本文就是从防止xss角度来说明一下Content-Security-Policy的使用方法。这个头信息,不设置在html里面的话,还可以从服务器端发出,比如nginx或者php之类的,都是可以发出这个header信息的。苏南大叔在这里就暂不赘述了。
更多csp的信息,可以查看下面的链接: