一、建立安全连接:HTTPS
HTTPS (全称:Hyper Text Transfer Protocol over SecureSocket Layer),是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证,保证了传输过程的安全性。HTTPS 在HTTP 的基础下加入SSL层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。 HTTPS 存在不同于 HTTP 的默认端口及一个加密/身份验证层(在 HTTP与 TCP之间)。
由于HTTP请求都是明文传输的,如果HTTP请求被黑客拦截,并且里面含有银行卡密码等敏感数据的话,会非常危险。为了解决这个问题,Netscape 公司制定了HTTPS协议,HTTPS可以将数据加密传输,也就是传输的是密文,即便黑客在传输过程中拦截到数据也无法破译,这就保证了网络通信的安全。
加密算法
- 对称加密
有流式、分组两种,加密和解密都是使用的同一个密钥。
例如:DES、AES-GCM、ChaCha20-Poly1305等 - 非对称加密
加密使用的密钥和解密使用的密钥是不相同的,分别称为:公钥、私钥,公钥和算法都是公开的,私钥是保密的。非对称加密算法性能较低,但是安全性超强,由于其加密特性,非对称加密算法能加密的数据长度也是有限的。
被公钥加密过的密文只能被私钥解密,过程如下:
明文 + 加密算法 + 公钥 => 密文, 密文 + 解密算法 + 私钥 => 明文
被私钥加密过的密文只能被公钥解密,过程如下:
明文 + 加密算法 + 私钥 => 密文, 密文 + 解密算法 + 公钥 => 明文
例如:RSA、DSA、ECDSA、 DH、ECDHE - 哈希算法
将任意长度的信息转换为较短的固定长度的值,通常其长度要比信息小得多,且算法不可逆。
例如:MD5、SHA-1、SHA-2、SHA-256 等
数字签名
发信端:信息经过hash算法转换成“摘要”,对“摘要”进行非对称加密,用公钥加密获得数字签名。
收信端:用私钥将数字签名解密,得到信件“摘要”,后将收到的信息经过hash算法生成序列,对比“摘要”,如果对比结果一致,说明信息没有被篡改。
数字证书
数字证书是由“认证中心”(Certificate Authority, CA)颁发的,用来认证公钥是否真的属于收信端。CA拥有自己的私钥,公钥公开给所有人。在需要传递收信端公钥的时候,CA用自己的私钥给收信端公钥和相关信息加密,生成数字证书。这样收信端有了数字证书的认证,给发信端回信的时候,发信端就可以用CA的公钥将数字证书解密,获得收信端公钥和相关信息,证明服务器的公钥没有被替换。
HTTPS通信过程
HTTPS协议 = HTTP协议 + SSL/TLS协议,在HTTPS数据传输的过程中,需要用SSL/TLS对数据进行加密和解密,需要用HTTP对加密后的数据进行传输,由此可以看出HTTPS是由HTTP和SSL/TLS一起合作完成的。
SSL的全称是Secure Sockets Layer,即安全套接层协议,是为网络通信提供安全及数据完整性的一种安全协议。SSL协议在1994年被Netscape发明,后来各个浏览器均支持SSL,其最新的版本是3.0
TLS的全称是Transport Layer Security,即安全传输层协议,最新版本的TLS(Transport Layer Security,传输层安全协议)是IETF(Internet Engineering Task Force,Internet工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本。在TLS与SSL3.0之间存在着显著的差别,主要是它们所支持的加密算法不同,所以TLS与SSL3.0不能互操作。虽然TLS与SSL3.0在加密算法上不同,但是在我们理解HTTPS的过程中,我们可以把SSL和TLS看做是同一个协议。
HTTPS为了兼顾安全与效率,同时使用了对称加密和非对称加密。数据是被对称加密传输的,对称加密过程需要客户端的一个密钥,为了确保能把该密钥安全传输到服务器端,采用非对称加密对该密钥进行加密传输,总的来说,对数据进行对称加密,对称加密所要使用的密钥通过非对称加密传输。
HTTPS在传输的过程中会涉及到三个密钥:
服务器端的公钥和私钥,用来进行非对称加密
客户端生成的随机密钥,用来进行对称加密
一个HTTPS请求实际上包含了两次HTTP传输,可以细分为8步:
1.客户端向服务器发起HTTPS请求,连接到服务器的443端口
2.服务器端有一个密钥对,即公钥和私钥,是用来进行非对称加密使用的,服务器端保存着私钥,不能将其泄露,公钥可以发送给任何人。
3.服务器将自己的数字证书(数字证书中含有服务器公钥和相关信息,由CA私钥加密)发送给客户端。
4.客户端收到服务器端的证书之后,会对证书进行检查,验证其合法性,如果发现发现证书有问题,那么HTTPS传输就无法继续。如果公钥合格,那么客户端会生成一个随机值,这个随机值就是用于进行对称加密的密钥,我们将该密钥称之为client key,即客户端密钥,这样在概念上和服务器端的密钥容易进行区分。然后用服务器的公钥对客户端密钥进行非对称加密,这样客户端密钥就变成密文了,至此,HTTPS中的第一次HTTP请求结束。
5.客户端会发起HTTPS中的第二个HTTP请求,将加密之后的客户端密钥发送给服务器。
6.服务器接收到客户端发来的密文之后,会用自己的私钥对其进行非对称解密,解密之后的明文就是客户端密钥,然后用客户端密钥对数据进行对称加密,这样数据就变成了密文。
7.然后服务器将加密后的密文发送给客户端。
8.客户端收到服务器发送来的密文,用客户端密钥对其进行对称解密,得到服务器发送的数据。这样HTTPS中的第二个HTTP请求结束,整个HTTPS传输完成。
简单说来: HTTPS的通信过程,就是报文内容被客户端的对称公钥加密,而客户端的对称公钥在传递的时候是被非对称加密的。
二、XSS攻击
跨网站指令码(英语:Cross-site scripting,通常简称为:XSS)是一种网站应用程式的安全漏洞攻击,是代码注入的一种。它允许恶意使用者将程式码注入到网页上,其他使用者在观看网页时就会受到影响。这类攻击通常包含了 HTML 以及使用者端脚本语言。
XSS 分为三种:反射型,存储型和 DOM-based
XSS漏洞容易出现在页面的输入框。例如在输入<script></script>或者eval()这种脚本语言时,如果网站存在XSS漏洞,那么恶意脚本很容易在页面上运行,攻击网站。
如何防御
- 最普遍的做法是转义输入输出的内容,对于引号,尖括号,斜杠进行转义。
- 将输入内容转成字符串格式后做处理。
- 采用白名单过滤的办法,将<h1>, <p>这些关键词收录在白名单中,白名单中的关键词不需要转义,白名单之外的内容需要进行转义后再做处理。
三、CSRF攻击
跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。跟XSS相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。
简单点说,CSRF 就是利用用户的登录态发起恶意请求。
CSRF攻击原理
- 首先用户C浏览并登录了受信任站点A;
- 登录信息验证通过以后,站点A会在返回给浏览器的信息中带上已登录的 cookie,cookie信息会在浏览器端保存一定时间(根据服务端设置而定);
- 完成这一步以后,用户在没有登出(清除站点A的cookie)站点A的情况下,访问恶意站点B;
- 这时恶意站点 B的某个页面向站点A发起请求,而这个请求会带上浏览器端所保存的站点A的cookie;
- 站点A根据请求所带的cookie,判断此请求为用户C所发送的。
因此,站点A会报据用户C的权限来处理恶意站点B所发起的请求,而这个请求可能以用户C的身份发送邮件、短信、消息,以及进行转账支付等操作,这样恶意站点B就达到了伪造用户C请求站点 A的目的。
受害者只需要做下面两件事情,攻击者就能够完成CSRF攻击:
- 登录受信任站点 A,并在本地生成cookie;
- 在不登出站点A(清除站点A的cookie)的情况下,访问恶意站点B。
很多情况下所谓的恶意站点,很有可能是一个存在其他漏洞(如XSS)的受信任且被很多人访问的站点,这样,普通用户可能在不知不觉中便成为了受害者。
如何防御
将cookie设置成http-only,使得恶意脚本无法访问cookie内容。
response.setHeader( "Set-Cookie","cookiename=cookievalue;HttpOnly");
将cookie开启same-site,该属性设置 Cookie 不随着跨域请求发送,禁止第三方网站访问cookie。
-
验证 Referer 来判断该请求是否为第三方网站发起的
利用Token。服务器下发一个随机 Token(算法不能复杂),每次发起请求时将 Token 携带上,服务器验证 Token 是否有效。例如在隐藏域中放入token,每次用户提交表单都会携带token,并与服务器token作对比。每次会话可以使用相同的token,会话过期,则token失效,攻击者因无法获取到token,也就无法伪造请求。
四、JWT Token
传统的session登录认证
在session认证中,用户信息存储在内存中,用户规模大之后增加服务器开销;由于登录信息存储在内存中,限制了登录机器,不利于分布式站点。
JWT认证
JWT(JSON Web Token) 是目前最流行的跨域身份验证解决方案,主要用于单点登录(Single Sign-On),单点登录是指在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
JWT由三部分组成,标头、有效载荷、签名。标头中包含token类型和哈希算法,有效载荷中包含标识用户的一些信息(例如签发者、用户名、签发时间、有效期等非敏感信息),签名由标头和有效载荷通过标头中的哈希算法生成。在JWT组合过程中,标头和有效载荷都通过Base64Url编码,与签名一起组成JWT串。JWT传输中,一般是将它放入HTTP请求头的Authorization字段中。
客户端接收服务器返回的JWT,将其存储在Cookie或localStorage中。此后,客户端将在与服务器交互中都会带JWT。一般是将它放入HTTP请求的Header Authorization字段中。当跨域时,也可以将JWT被放置于POST请求的数据主体中。
JWT的最大缺点是服务器不保存会话状态,所以在使用期间不可能取消令牌或更改令牌的权限。也就是说,一旦JWT签发,在有效期内将会一直有效。JWT本身包含认证信息,因此一旦信息泄露,任何人都可以获得令牌的所有权限。为了减少盗用,JWT的有效期不宜设置太长。对于某些重要操作,用户在使用时应该每次都进行进行身份验证。
五、同源策略
如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源。同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以xyz.com下的js脚本采用ajax读取abc.com里面的文件数据是会被拒绝的。
同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。
跨域解决方案:
- JSONP
- CORS标准(简单请求和非简单请求)
- window.postMessage(iframe)
- websocket
websocket协议的出现时为了解决http协议单向请求的缺点,支持服务器主动向客户端推送信息,客户端也可以主动向服务器发送信息,两者平等对话。websocket协议建立在 TCP 协议之上,服务器端的实现比较容易;与 HTTP 协议有着良好兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器;数据格式比较轻量,性能开销小,通信高效;可以发送文本,也可以发送二进制数据;没有同源限制,客户端可以与任意服务器通信。协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。 - Nginx反向代理
阮一峰老师的跨域解决方案:浏览器同源政策及其规避方法
CORS详解:跨域资源共享 CORS 详解
参考文献
https://www.jianshu.com/p/14cd2c9d2cd2
http://www.ruanyifeng.com/blog/2011/08/what_is_a_digital_signature.html
https://yuchengkai.cn/docs/frontend/safety.html#xss
https://www.jianshu.com/p/67408d73c66d
https://www.jianshu.com/p/6c4e1804653f