Web安全快速入门
──几个Web开发人员必知的安全缩略语
原文:
作者: 发表时间:2018/8/15
译者: 发表时间:2018/8/25
(转载请注明出处)
你有很多理由需要了解Web安全,比如:
- 你是一位关心个人隐私数据正被泄露的用户
- 你是一名Web开发人员,想要编写更加安全的Web应用
- 你是一位正在应聘Web开发岗位,准备面试有关Web安全问题。
- 诸如此类~
本文将通俗易懂的准确地解释一些常用的Web安全缩略语。
在此之前,我们要了解两种模式,分别代表着两个极端,但又同属一个观念层次。
安全的两个模式
一种模式是追求绝对安全,结果无论如何努力也达不到绝对安全,而弄得自己痛苦不堪。
另一种是在采取了一定的防护措施后,便满足地认为已达到绝对安全,于是放松警惕,最后遭受安全威胁的攻击,损失惨重。
你不能就说:
喔,因为实现了CSP,所以我是安全的。我可以在漏洞清单中划掉跨站脚本,因为它不会发生。
你会发现自己和其他人一样,也是按这种方式思考的。显而易见,程序员们很容易按这种方式思考:非黑即白,非0即1,非对即错。其实,安全远没有这么简单。
我们在Web开发工作中初期就遇到会这些问题,并尝试从StackOverflow社区中能找到解决方案。
跨源资源共享(CORS)
你是否见到类似下面的错误信息?
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.复制代码
你不是一个人在战斗,你Google查询,有人说用这个方法,所有问题马上解决。
太好了,不是吗?
CORS是来保护你而不是伤害你的
为了解释CORS是如何帮助你的,让我们先从cookie说起,特别是认证cookie。认证cookie是用来告诉后台程序你的登录状态,它们自动随任何请求发送给后台程序。
我们来假设:你已经登录了Facebook账户,且Facebook使用cookie认证。你点击链接bit.ly/r43nugi
,它重定向到恶意网站 superevilwebsite.rocks
。恶意网站 superevilwebsite.rocks
中的一段脚本代码向facebook.com
后台程序发起请求,你的认证cookie自动随请求发送给facebook.com
后台程序。
在非CORS的世界,黑客可以在你毫不知情的情况下变更你的账户。只需要简单几步:1、黑客在你的时间线上发帖,帖子中包含bit.ly/r43nugi
恶意链接;2、你的朋友们点击了该恶意链接,恶意脚本程序又在他们的时间线上发帖,这个过程不断被重复,在广度优先模式下,直到黑客占领了全部的Facebook用户的时间线,世界充斥着恶意网站 superevilwebsite.rocks
。 ?
然而在CORS的世界,Facebook将只允许来源自facebook.com
的请求方可在后台程序中修改数据。换句话说,他们会限制跨源资源共享。你可能会问:
我们可以修改请求文件头,这样请求不就看起来是来自facebook.com吗?
你可以试试,但不会成功的,因为浏览器会忽略你的修改,它会使用真正的来源信息。
好了,那如果恶意网站修改后台程序的请求呢?
在这种情况下,你想绕过CORS,但你还是不会得逞,原因后台程序不能同时发送你的认证cookie。脚本必须在浏览器上执行才能获取到你存在浏览器上的cookie。
内容安全策略(CSP)
为了便于理解CSP,我们先谈一下最常见的Web漏洞:跨站脚本攻击(简称:XSS)
XSS即黑客在你的浏览器中注入JavaScript代码。你可能会想:
黑客会做什么,红变绿吗?
我们假如黑客在你的浏览器成功中注入JavaScript代码到你正在访问的网站代码中。
他们可能会做哪些邪恶的事情?
- 他们能冒充你向其他网站发送HTTP请求。
- (这句不会翻,囧)
- 他们能加script标签,内嵌的一段JavaScript代码。
- 他们能加script标签,引用远程的JavaScript代码。
- 他们能内嵌一个网页覆盖正常网页之上,提示你输入密码。
- 罄竹难书,发挥你的想象力吧。
CSP通过限制功能提供保护:
- 什么能在框架内打开。
- 什么样式表可以被加载。
- 哪些请求可以发送,等等。
那它时怎么工作的呢?
等你点击链接或在浏览器地址栏输入网址的时候,浏览器发送GET请求。服务器返回HTTP头信息以及HTML内容。如果你对返回头信息是什么很好奇,(以谷歌Chrome浏览器为例,打开浏览器开发者模式。括弧内为译者补充,下同)切换到“网络”标签,访问网站facebook.com
。
你可能会看到如下返回头信息:
content-security-policy: default-src * data: blob:;script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' *.atlassolutions.com blob: data: 'self';style-src data: blob: 'unsafe-inline' *;connect-src *.facebook.com facebook.com *.fbcdn.net *.facebook.net *.spotilocal.com:* wss://*.facebook.com:* https://fb.scanandcleanlocal.com:* *.atlassolutions.com attachment.fbsbx.com ws://localhost:* blob: *.cdninstagram.com 'self' chrome-extension://boadgeojelhgndaghljhdicfkmllpafd chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm;复制代码
这些是facebook.com
的安全内容策略。让我们调整成可读性强的格式。
content-security-policy:default-src * data: blob:;script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' *.atlassolutions.com blob: data: 'self';style-src data: blob: 'unsafe-inline' *;connect-src *.facebook.com facebook.com *.fbcdn.net *.facebook.net *.spotilocal.com:* wss://*.facebook.com:* https://fb.scanandcleanlocal.com:* *.atlassolutions.com attachment.fbsbx.com ws://localhost:* blob: *.cdninstagram.com 'self' chrome-extension://boadgeojelhgndaghljhdicfkmllpafd chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm;复制代码
现在,我们逐条分解这些指令。
**default-src**
限制所有其他没有显示列出的CSP指令。**script-src**
限制脚本加载。**style-src**
限制样式表加载。**connect-src**
限制可以使用脚本接口(如获取、XHR、ajax等)的URL链接。
注意远不止这3条指令,还有更多的CSP指令。浏览器将读取CSP头信息并加载、渲染HTML文件时执行这些指令。如果恰当地设置指令,浏览器将仅允许必要的操作。
如果没有CSP头信息,那么所有的操作都不会被限制。你可以想象这些指令全部替换成通配符*
,任何操作都将被允许。
HTTPS 或 HTTP安全
你肯定听说过HTTPS。人们可能会这么说:
为何我要关心一个我玩游戏的网站是否启用了HTTPS呢?
或者是这样滴。。。
太疯狂了,你的网站居然没有启用HTTPS。都2018年了,别信其他人(潜台词:必须启用HTTPS)。
或许你听说谷歌Chrome浏览器(自7月24日发布的Chrome 68起)将把所有HTTP网站标记“不安全“。
重点是,HTTPS是加密的而HTTP不是。
如果你不发送敏感信息,(是否加密)有那么重要吗?
准备下一个缩写MITM,它代表中间人攻击。
如果你在咖啡馆使用无密码的公共Wi-Fi,任何人都很容易地冒充成路由器,使全部的请求和返回都通过该路由器。如果你的数据没有加密,那么他们可以做任何事。比如在HTML, CSS, 或 JavaScript到达你的浏览器之前修改。假如你已经知道XSS,那么可以做什么样的坏事。
那么怎样才可以实现我的电脑和服务器之间通信加密而不被中间人攻击呢?
最初SSL协议就是为了解决这个问题而设计的,1999年,TLS协议取代SSL协议用在HTTPS上。至于TLS如何工作已经超出本文范围。
HSTS协议
让我们还用Facebook的头信息为例,以下是一条很简洁的指令。
strict-transport-security: max-age=15552000; preload复制代码
max-age
标明HSTS在浏览器的生效时间。preload
对本文不重要。
这个头信息仅在用HTTPS访问时生效,在用HTTP访问时会被忽略。原因很简单,HTTPS时如此不安全,很难被信任。
让我们用Facebook的例子来描述下。你首次访问facebook.com
,而且知道HTTPS比HTTP安全,所以你使用https://facebook.com
。当浏览器接收到HTML,收到头信息,告知浏览器在后续访问中强制重定向到HTTPS网站。一个月后,有人通过HTTP给你发送一个Facebook的链接,比如http://facebook.com
,在max-age
时间范围内,浏览器会强制使用HTTPS,防止潜在的中间人攻击。
结论
无论你在Web开发旅程中的何时何地Web安全都很重要。你越重视它,安全威胁离你越远。安全时对每个人都很重要的事情,而不仅是对于工作中。?