这是我参与「第四届青训营 」笔记创作活动的第2天
前言
无论各行各业安全都是第一重要的问题,在当今大前端的趋势下,Web安全也越来越重要,下面我简要介绍常见的Web安全问题。
CSRF
什么是CSRF
CSRF(Cross-Site Request Forgery)跨站请求攻击,主要原理是利用http请求自动携带cookie的特性做出恶意请求获得用户隐私数据或执行恶意操作。这可能十分抽象,下面我会给出更详细的机制并且举个例子。
目前大部分网站的登录权限验证都是通过session会话方式,即用户在某网站登陆后,服务端会保存一个键值对记录其登录信息,并返回带有session.id(即服务端内保存的键)的cookie。并在之后请求该网站的任意接口时都会携带cookie,然后服务端通过里面的session.id来获取用户信息完成登录权限验证。下面我举个栗子:
假设淘宝的购买商品接口有CSRF漏洞,在此前提下有一个用户登陆过淘宝,此时用户的session.id被存储在cookie中,然后用户又点开了一个攻击者的钓鱼网站,这个网站在被打开时会发送一个购买淘宝某商品的请求,此时该请求就会自动携带用户的cookie,服务端便会通过该cookie获取用户信息完成登录权限认证并认为是用户要购买该商品而非攻击者,但用户完全不知道。
CSRF危害
- 利用CSRF漏洞完成一系列网站授权给用户允许做的事如购买商品、获取用户新、修改用户信息等等。
- 通过CSRF漏洞触发其它安全漏洞。
- CSRF蠕虫。 其它都很容易理解,那什么是CSRF蠕虫呢?其实十分类似于现在网络上我们常见的利用社交软件的诈骗手段,如好友QQ号被盗取发送钓鱼链接欺骗点击然后一传十十传百的病毒式传播。CSRF蠕虫也是一样的,假设某社交网站的获取用户信息与获取好友列表接口有CSRF漏洞,那么攻击者通过CSRF攻击获取到一个人的用户信息并通过好友列表发送钓鱼链接的一个循环过程,就是CSRF蠕虫。
如何防御
- 检查请求头字段Referer
- Token验证
Referer防御
浏览器在发送请求时,请求头中有一个Referer字段,我们可以通过检查Referer字段来拒绝非同站的请求。
Token验证
我们这里详细介绍JWT(JSON Web Token)鉴权,该方式是通过前端记录token,每次通过请求通过Header中添加认证头的方式进行登录权限验证。
什么是JWT
JWT是一个规范,允许我们使用JWT在用户和服务器之间安全可靠地传输信息。
JWT由三部分组成:header(头部)、payload(载荷)、signature(签证)这三部分以小数点连接起来。
头部(header)
header一般声明所采用的加密算法和类型并且对其进行base64编码得到。
载荷(payload)
载荷一般是需要传输的信息并对其进行base64编码得到。但由于载荷可在客户端进行解码,所以不建议存储敏感信息如密码。
签证(signature)
签证的生成公式如下:
加密算法为头部所声明的加密算法,密钥保存在服务端,客户端无法知道密钥,故服务端进行JWT验证时只需要根据以上公式计算得到签证比将其与传输过来的JWT的签证比较是否相同就能完成验证,无需查询数据库等操作所以十分受欢迎。
XSS
XSS一般有以下几类:
- 存储型(Stored XSS)
- 反射型(Reflected XSS)
- 基于DOM型(DOM-based XSS)
- 特定浏览器型(Mutation-based XSS) 在介绍这几类XSS攻击前,我们先了解一下什么是XSS。
什么是XSS
XSS全称为Cross-Site Scripting——跨站脚本攻击,因为缩写与CSS一致故改叫XSS。XSS攻击是是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如Cookie、SessionID等,进而危害数据安全。
XSS本质是:盲目相信用户的输入导致攻击者可以将恶意代码注入进正常的代码,浏览器无法分辨哪些脚本是可信的导致恶意脚本被执行。如下图:
又因为是在浏览器端执行,故恶意脚本能够直接获取用户信息或利用这些信息冒充用户向网站发起攻击者定义的请求。
存储型XSS(Stored XSS)
存储型XSS是危害性最大的一种XSS攻击。它将恶意代码注入进数据库,当用户每一次访问需要查询被注入恶意代码的数据库便会执行一次恶意脚本。具体步骤如下:
- 攻击者将恶意代码提交到被攻击网站的数据库中。
- 用户打开被攻击网站时,服务器读取数据库将恶意代码读出并拼接在HTML中返回。
- 浏览器接收响应并解析执行服务器端返回的代码,此时恶意代码也会执行。
- 攻击者利用恶意代码窃取用户数据或假冒用户做出各种行为。
反射型XSS(Reflected XSS)
反射型XSS是利用URL链接中的参数进行恶意代码注入。所以反射型攻击不涉及数据库。具体步骤如下:
- 通过表单的提交、搜索等功能或自行构造出一个特殊的URL,通常URL携带的参数里带有恶意代码。
- 用户打开带有恶意代码的URL时,服务器将URL中的恶意代码取出并拼接成HTML返回给浏览器。
- 浏览器接受响应解析并执行服务器端返回的代码,此时恶意代码也被执行。
- 攻击者利用恶意代码窃取用户数据或假冒用户做出各种行为。
基于DOM型(DOM-based XSS)
基于DOM型的XSS很容易理解,就是攻击者基于DOM树注入恶意代码,一般为前端未做特殊字符转义被注入恶意代码后浏览器执行,故不需要服务器的参与。
- 通过表单的提交、搜索等功能或自行构造出一个特殊的URL,通常URL携带的参数里带有恶意代码。
- 用户打开带有恶意代码的URL。
- 浏览器接收服务器的响应后解析并执行,然后前端JS取出URL中的恶意代码并执行。
- 攻击者利用恶意代码窃取用户数据或假冒用户做出各种行为。
特定浏览器型(Mutation-based XSS)
特定浏览器型如其字意,不同的浏览器有不同的内核,故有不同的渲染机制,利用浏览器渲染机制进行恶意代码注入,故不同浏览器会有区别。
这一攻击笔者也不熟悉,感兴趣的可自行搜索。
如何防御XSS攻击
通过前面几大类型的XSS介绍相信大家也都发现了一个规律:
- 攻击者总是需要提交恶意代码。
- 浏览器总是执行恶意代码。 但是我们又不能区分攻击者与正常用户的请求提交,浏览器也区分不了正常代码与恶意代码,那我们该怎么办呢?这里笔者直接给出结论:
- 防止HTML出现注入,即尽量避免出现返回拼接HTML这种情况。
- 防止JS执行时执行恶意代码。 第一种方法后端可以采用成熟的HTML转义库或将数据与代码分隔开,前端负责渲染,如采用Vue/React这类成熟框架,后端负责提供数据即可。这种方法可以预防存储型XSS与反射型XSS。
第二种方法即前端代码尽可能避免使用.innerHTML,.outerHTML,document.write()等API,当使用这些API时应慎之又慎,考虑可能出现的输入情况。
仅靠我们开发者将XSS做至完美是不可能的,故还有各种协议如CSP(Content Security Policy)内容安全协议,协议方面笔者就不多做赘述了,有耐心可以啃英文文档。
DDOS
DDOS有以下几类攻击:
- 应用程序层攻击
- 协议攻击
- 容量耗尽攻击
什么是DDOS
DDOS(Distributed Denial of Service)分布式拒绝服务,通过大规模的互联网流量淹没目标服务器及其周边设施,以破坏目标服务器、服务或网络正常流量的恶意行为。
即通过大规模的恶意请求使服务器无法响应用户正常的请求。
应用程序层攻击
此类攻击原理为客户端发起HTTP请求比服务器端响应HTTP请求的成本低,因为服务器响应需要查询数据库、加载多个文件等。这类攻击很难防御因为无法区分合法流量与恶意流量。
协议攻击
协议攻击又称为状态耗尽攻击,这类攻击会过度消耗服务器资源或负载平衡器之类的网络设备资源,从而导致服务器拒绝服务。
这类攻击一般利用TCP协议的限制进行攻击。
我们都知道TCP的三次握手,而攻击者在建立TCP过程中只发送SYN请求,不发送确认收到SYN-ACK的请求,导致连接未建立空耗服务器资源,攻击者发送大量的此类请求便能使服务器拒绝服务。
容量耗尽攻击
此类攻击通过消耗目标与较大的互联网之间的所有可用带宽来造成拥塞。攻击运用某种放大攻击或其他生成大量流量的手段,向目标发送大量数据。
防护DDOS攻击
后记
安全无小事,这里只是常见的几种攻击手段与预防措施,攻击者的手段与方法也会与时俱进,希望大家的个人网站都不被攻击😊。笔者是新人前端,文章如有错误还请海涵,欢迎勘误交流。