“安全”一直是互联网企业关心的问题,一旦发生安全事故,后果几乎是毁灭性的,例如2014年全球最大的比特币交易平台Mt.Gox由于交易系统出现漏洞,损失估计达到4.67亿美元,被迫宣布破产。但“安全”是个很庞大的问题,涉及面非常的广,下面主要讲前端的安全性问题。
一、TCP/IP传输协议
我们先从底层开始讲,所有的页面都是通过TCP/IP协议传输,因此要保证传输的数据是安全的,那么必须底层也是安全的。
TCP/IP分层管理
TCP/IP分为四层:应用层、传输层、网络层和数据链路层。
- 数据链路层,也可以称为物理传输层,因为这一层主要涉及原始数据的物理传输,例如双绞线、WIFI就是这一层不同协议的实现。
- 网络层,负责数据的传输路径,例如数据从IP: 137.17.147.7传输到137.17.147.8,要经过什么路线,都是由这一层决定,我们常说的IP, MAC就是这一层的协议。
- 传输层,主要负责数据使用何种数据结构进行传输,http的80端口,ssh的22端口都是这一层的产物。
- 应用层,主要负责处理接收到的数据,例如浏览器展示接收到的http数据,然后执行js等等工作。
虽然这四层一环扣一环,但他们并不关心各层的处理方式,他们各有各的协议,并且它们之间都是绝对的信任。
传输流程
假如我们在地址栏上输入地址,按下回车,到网页展示在我们面前,这过程发生了什么?
TCP三次握手
用户首先跟服务器说:Hi,我要发信息过来了,服务器接到到之后会回答客户机说:我收到了,你可以开始发数据了吗?用户回答说,好,我现在开始发喽,这时候客户机与服务器就建立起一条可以持续发送数据的通道。很显然,握手的过程非常烦锁,产生的延迟非常严重,但好处是可以保证传输的正确性。
数据封装和提取
数据从一层向另一层交换数据时都会封装或提取数据,例如:用户与服务器握手之后,用户发送GET请求,地址是www.baiduc.om ,浏览器会把地址封装成http请求报文(应用层),然后再贴上ip地址和端口组成IP包(传输层),再然后贴上mac地址(网络层),最后贴上校验码、传输协议等信息( 数据链路层),这样就可以在网线或wifi中传输,当服务器收到之后就会一层一层地提取数据,当服务器解开数据知道是请求百度首页,服务器就会像用户一样,一层一层的封装数据,然后发给用户。
各层常见的安全问题
- 在数据链路层常见有嗅探攻击,利用嗅探器获取网络链路中的所有数据,然后过筛选就可得到想要的数据。由于http使用明文传输,因此用户访问过什么网站,cookie是多少,甚至用户名和密码都能获取到,对安全性影响非常大。防范手段并不复杂,只要使用了加密传输,嗅探器只能捕获一连串无意义的乱码,例如使用https浏览网站,基本上就不用考虑嗅探攻击的问题,但由此会造成网页传输效率降低的问题,需要衡量这个成本。
- 第二层比较常见的攻击手段是劫持,特别是运营商的内容劫持,常会在页面出现一个运营商的悬浮球,防范手段跟上面一样,改用https即可,因为https会对内容进行加密,运营商就无法修改里面的内容了。另外也很常见的手段是ip欺骗,arp欺骗,来劫持页面的流量。
- 第三层有非常著名的DOS攻击(服务器拒绝攻击),到现在仍没有完美的解决办法,唯一解决途径就是通过高价购买防DOS攻击服务,很多安全公司会通过这方法来勒索钱财。
-
二、HTTP协议
目前流行的大多客户端仍使用1997年的http协议,也就是http1.1,http2.0有很多改善,性能大幅提升,但还没有普及,并且有很多地方沿用http1.1,所以这里学习http1.1也算是打基础。
基本通信流程
http通信是基于tcp/ip,当三次握手之后,浏览器就可以发送http请求报文,服务器接收到请求之后,就会返回服务器上的内容。下面几个关键点:
http是无状态(no session)的协议,也就是说客户端与服务端都不会保存之间的信息,cookie并不是http协议(1.1)里的内容,但它在现代网页中,用于客户端和服务端的状态具有关键的作用。
http1.1在tcp通道建立之后默认会保存一段时间(connection: keep-alive),以便于快速传输页面内容,一个页面里的一个域名允许有多个通道。
基本数据结构
无论请求报文(request)还是返回报文(response),它们的结构都是相同的,它们本身都是文本结构,都包含有头部信息(header)和数据主体(body)。http协议定义的大部分内容都在头部信息,所以下面主要讲解各个头部内容。
头部信息
请求头部:请求报文的头部信息主要用于告诉服务器“我能接收什么样的内容”。例如客户端的语言、编码、缓存机制、cookie内容,甚至地理位置等等。
返回头部:返回报文的头部主要告诉客户端最终使用的内容格式,例如语言、编码、缓存时长、缓存范围、cookie设置等等。主体数据
请求主体:根据客户端的需要,可以为空,例如GET请求。也可以为用户提交的数据,例如JSON、二进制流媒体、FormData等等。
返回主体:常见的有html文本、JavaScript、css、JSON、图片、视频等等。常见的http攻击手段
http协议没有包含安全功能的内容,本身设计也不存在安全问题,主要是利用http对客户端和服务器进行攻击。
Cookie攻击
Cookie用于保存用户与服务端之间的会话,服务端通过cookie的session id来区分用户,例如银行网站A会向用户A设置cookie中sessionId的值为A123456,用户A每次向网站A请求都会附上cookie的值,服务器通过读取cookie中session id的值就可以判断是那个用户了。如果某个不怀好意的用户B,通过某种手段获取到用户A的sessionID(例如在网站A评论上嵌入恶意代码,用户A浏览时就会执行该段代码,并发送cookie到用户B指定的地方),那么用户B就可以通过改变自已的sessionId为A123456来欺骗服务器,从而进行破坏,例如转走用户A的钱。为了防止cookie泄露,网站应设置httponly参数,以防javascript读取到cookie的值;适当增加sessionId的复杂度;在非必要情况下尽量少用或不用cookie来保存用户数据;适当减短cookie的过期时间;尽量不要把sesstionId放到url上。
CSRF攻击
在上面通过各种手段加强了cookie的安全性后,用户B无法获取到用户A的cookie,也就无法劫持用户A的会话了,但聪明的用户B并不放弃,他在网站A评论中嵌入一个隐藏的图片,地址是
www.exampleA.com/transfer/toUser?id=B123456&amount=10000
,这个地址的意思是向用户B转账1万元,当用户A点开之网站A的评论后,浏览器就自动会请求隐藏图片的地址,并且会自动附上用户A的cookie!这样用户B就成功转走了用户A账户的资金。为了安全,网站A不得不把所有接口的请求方式改为POST,监于网站一般会过滤<script >
标签,这样就无法直接跨站调用了。但聪明的用户B,通过伪造form,并且成功诱导用户A点击,成功发送了转账请求。最终,网站A使出了终极技能:csrf token校验,才成功阻止所有csrf攻击。XSS攻击
XSS攻击就是上面用户B利用评论区的漏洞,在评论上写js脚本,从而使所有人打开网站A的时候就执行了用户B的脚本。但由于网站A的评论区添加了
<script>
标签的过滤功能,用户B不能直接写js了,但很多dom元素即使不用script标签也能执行js脚本,例如:<img onerror="alert('xss attack')" src='404'>
,这样当图片加载失败后就会弹窗,用户B利用这些漏洞继续攻击用户A的资金。网站A为了杜绝XSS攻击加强了过滤功能,甚至图片都不允许上传了,并且把所有用户展示的内容都进行转码(escape),下面是一个最简单的转码函数:const sanitizeHTML = function (str) {
var temp = document.createElement('div');
temp.textContent = str;
return temp.innerHTML;
};
SQL注入攻击
SQL注入攻击是互联网最流行的攻击手段,例如用户B想知道网站A上谁比较有钱,B就需要查看各用户的账户,他发现可以调用
http://www.exampleA.com/view/account?id=1
这样的接口来查看用户的账户,用户B可以联到想这样的SQL语句SELECT * FROM Users WHERE id = '1'
,如果用户B把1改成1'; SELECT * FROM Users WHERE id = '2
,他就有可能查询到用户id=2的资金账户。这就是一个典型的SQL注入攻击。三、HTTPS协议
服务器与客户端通信时,会经过很多不同的设备,例如网关、路由、中继、代理等等,这些设备都是不可见,也不可信的,谁也不能保证会在那个设备里做手脚,为了保证传输内容的安全,WEB常用https协议进行加密传输。https是一种被广泛认可的、安全的传输协议,例如Google、facebook等公司都全部用上了https。
基本原理
HTTPS全称是HTTP over TLS、HTTP over SSL,HTTP over secure(安全),也就是基于TLS或SSL的超文本传输协议,所以要理解什么是HTTPS,就首先要认识HTTP和TLS、SSL,HTTP前面已经说过了,但什么是TLS和SSL呢?
TLS和SSL
TLS是Transport Layer Security的缩写,SSL是Secure Sockets Layer的缩写,SSL是TLS的前身。TLS通过握手协议,在两端之间建立安全的、不可监听的通道。
客户端利用算法随机生成一串字符,用作会话钥(Session key),然后用公钥(public key)加密,生成加密后的会话钥,发给服务器。
- 服务端收到加密后的会话钥,利用私钥(private key)解开,得到会话钥,由于用公钥加密后的会话钥只有私钥才能解开,这就是为什么TLS通信是安全的关键点。
- 客户端发送信息前,利用会话钥对信息加密,然后发给服务器,服务器利用会话钥可以迅速地解读信息。
基于TLS
在TLS通道建立之后,客户端就会利用该通道发送HTTP报文,HTTPS并不会修改HTTP的内容,它只负责加密和解密。HTTP vs HTTPS
HTTPS的优势是安全,但是否必须使用HTTPS呢?HTTPS延迟较长
即使利用各种手段进行优化,HTTPS目前的延迟还是比较明显,对于一些时效性比安全性更重要的内容,HTTP还是首选,例如CSS、图片、多媒体等等。HTTPS费用较大
由于https需要证书,而且获取证书每年都要花费不小的费用,同样,使用CDN流量费用也会相对多一点,如果对财务问题比较敏感的情景,建议使用HTTP。HTTPS占用更多的服务器资源
由于现代电脑速度非常快,客户端加密信息并不会明显拖慢电脑,但对于服务器来说,连接数多的时候,需要大量的浮点运算,导致服务器明显变慢。HTTPS是未来的趋势
再怎么说,HTTP是相对不安全的,在任何需要相对安全的情景下HTTPS还是首选,例如银行网站。不过随首技术的提升,通过优化,https可以把延迟降到http的水平,费用、服务器资源等问题,随着市场的竞争,也会降低到一个合理水平。我相信未来https会替换http成为行业首选。四、总结
随着用户对安全的要求越来越高,我们也要增加相应的人力物力的投入,不断地提升产品的安全性,作为程序员也要多学习新的加密算法,以应对更多的安全需求。