参考文章:
XSS
概念
Cross-Site Scripting(为了和CSS区分开缩写为XSS),即跨站脚本攻击,是一种代码注入攻击。攻击者在目标网站上注入恶意代码,当用户登陆网站时就会执行这些恶意代码,这些脚本可以读取 cookie,session tokens ,或者其它敏感的网站信息,进而危害数据安全。
XSS 的本质是因为网站没有对恶意代码进行过滤,与正常的代码混合在一起了,浏览器没有办法分辨哪些脚本是可信的,从而导致了恶意代码的执行。
攻击者可以通过这种攻击方式可以进行以下操作:
- 获取页面的数据,如DOM、cookie、localStorage;
- DOS攻击,发送合理请求,占用服务器资源,从而使用户无法访问服务器;
- 破坏页面结构;
- 流量劫持(将链接指向某网站)
常见攻击方式
类型 | 存储区(恶意代码存放的位置) | 插入点(由谁取得恶意代码,并插入到网页上) |
---|---|---|
存储型 XSS | 后端数据库 | HTML |
反射型 XSS | URL | HTML |
DOM 型 XSS | 后端数据库/前端存储/URL | 前端 JavaScript |
反射型(非持久型)
反射型指的是攻击者诱使用户点击一个恶意链接,或者提交一个表单,或者进入一个恶意网站时,注入脚本进入被攻击者的网站。
- 攻击者构造出特殊的 URL,其中包含恶意代码。
- 用户打开带有恶意代码的 URL 时,网站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器。
- 用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
- 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。
存储型(持久型)
存储型 XSS 会把用户输入的数据"存储"在服务器端,当浏览器请求数据时,脚本从服务器上传回并执行。这种 XSS 攻击具有很强的稳定性。
- 攻击者将恶意代码提交到⽬标⽹站的数据库中。
- ⽤户打开⽬标⽹站时,⽹站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器。
- ⽤户浏览器接收到响应后解析执⾏,混在其中的恶意代码也被执⾏。
- 恶意代码窃取⽤户数据并发送到攻击者的⽹站,或者冒充⽤户的⾏为,调⽤⽬标⽹站接⼝执⾏攻击者指定的操作。
基于DOM
基于 DOM 的 XSS 攻击是指通过恶意脚本修改页面的 DOM 结构,是纯粹发生在客户端的攻击。
- 攻击者构造出特殊的 URL,其中包含恶意代码。
- ⽤户打开带有恶意代码的 URL。
- ⽤户浏览器接收到响应后解析执⾏,前端 JavaScript 取出 URL 中的恶意代码并执⾏。
- 恶意代码窃取⽤户数据并发送到攻击者的⽹站,或者冒充⽤户的⾏为,调⽤⽬标⽹站接⼝执⾏攻击者指定的操作。
反射型 XSS 与存储型 XSS 的区别
- 存储型 XSS 的恶意代码存在数据库里,反射型 XSS 的恶意代码存在 URL 里
- 反射型 XSS 漏洞常见于通过 URL 传递参数的功能,如网站搜索、跳转等。由于需要⽤户主动打开恶意的 URL 才能⽣效,攻击者往往会结合多种⼿段诱导⽤户点击。
DOM 型 XSS 跟前两种 XSS 的区别
- DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞
防御方式
纯前端渲染
纯前端渲染中,我们会明确的告诉浏览器:下面要设置的内容是文本(.innerText
),还是属性(.setAttribute
),还是样式(.style
)等等。浏览器不会被轻易的被欺骗,执行预期外的代码了。
转义 HTML
如果拼接 HTML 是必要的,就需要采用合适的转义库,对 HTML 模板各处插入点进行充分的转义
使用 CSP
CSP 意为内容安全策略,它的本质是指定有效域(建立一个白名单),告诉浏览器哪些外部资源可以加载和执行。我们只需要配置规则,如何拦截由浏览器自己来实现。
通过设置 HTTP 首部中的 Content-Security-Policy或设置 meta 标签的方式开启CSP
使用 HttpOnly 防止劫取 Cookie
HttpOnly 最早由微软提出,至今已经成为一个标准。浏览器将禁止页面的 Javascript访问带有 HttpOnly 属性的Cookie。
攻击者可以通过注入恶意脚本获取用户的 Cookie 信息。通常 Cookie 中都包含了用户的登录凭证信息,攻击者在获取到 Cookie 之后,则可以发起 Cookie 劫持攻击。所以,严格来说,HttpOnly 并非阻止 XSS 攻击,而是能阻止 XSS 攻击后的 Cookie 劫持攻击。
使用验证码
防止脚本冒充用户提交危险操作。
CSRF
概念
Cross-site request forgery,即跨站请求伪造,攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。
由于 Cookie 中包含了用户的认证信息,当用户访问攻击者准备的攻击环境时,攻击者就可以对服务器发起 CSRF 攻击。在这个攻击过程中,攻击者借助受害者的 Cookie 骗取服务器的信任,但并不能拿到 Cookie,也看不到 Cookie 的内容。而对于服务器返回的结果,由于浏览器同源策略的限制,攻击者也无法进行解析。因此,攻击者无法从返回的结果中得到任何东西,他所能做的就是给服务器发送请求,以执行请求中所描述的命令,在服务器端直接改变数据的值,而非窃取服务器中的数据。
CSRF 攻击的本质是利用 cookie 会在同源请求中携带发送给服务器的特点,以此来实现用户的冒充。
常见攻击方式
GET 类型的 CSRF 攻击
比如在网站中的一个 img 标签里构建一个请求,当用户打开这个网站的时候就会自动发起提交。
POST 类型的 CSRF 攻击
比如构建一个表单,然后隐藏它,当用户进入页面时,自动提交这个表单。
链接类型的 CSRF 攻击
比如在 a 标签的 href 属性里构建一个请求,然后诱导用户去点击。
防御方式
因为攻击一般发起在第三方网站,而不是被攻击的网站,因此被攻击的网站无法防止攻击发生,只能通过增强自己网站针对CSRF的防护能力来提升安全性。
同源检测
因为攻击一般发起在第三方网站,所以可以直接禁止外域(或者不受信任的域名)对我们发起请求。
在HTTP协议中,每一个异步请求都会携带两个Header,用于标记来源域名:
- Origin Header
- Referer Header
这两个Header在浏览器发起请求时,大多数情况会自动带上,并且不能由前端自定义内容。服务器可以通过解析这两个Header中的域名,确定请求的来源域。
如果Origin存在,那么直接使用Origin中的字段确认来源域名就可以。
但是Origin在以下两种情况下并不存在:
- IE11同源策略:
IE 11 不会在跨站CORS请求上添加Origin标头,Referer头将仍然是唯一的标识。最根本原因是因为IE 11对同源的定义和其他浏览器有不同,有两个主要的区别:- 如果两个域都在高度信任的区域(例如公司 Intranet 域),则不应用同源限制
- IE 不将端口包含在同源检查中。
- 302重定向:
在302重定向之后Origin不包含在重定向的请求中,因为Origin可能会被认为是其他来源的敏感信息。对于302重定向的情况来说都是定向到新的服务器上的URL,因此浏览器不想将Origin泄漏到新的服务器上。
在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP 请求的来源地址。通过 Referer Check,可以检查请求是否来自合法的"源"。
但是攻击者可以在自己的请求中隐藏Referer,另外在以下情况下Referer没有或者不可信:
- IE6、7下使用window.location.href=url进行界面的跳转,会丢失Referer。
- IE6、7下使用window.open,也会缺失Referer。
- HTTPS页面跳转到HTTP页面,所有浏览器Referer都丢失。
- 点击Flash上到达另外一个网站的时候,Referer的情况就比较杂乱,不太可信。
当 origin 或者 referer 信息都不存在的时候,直接阻止请求。缺点是有些情况下会把搜索引擎的链接也给屏蔽了。所以一般网站会允许搜索引擎的页面请求,但是相应的页面请求这种请求方式也可能被攻击者给利用。
Samesite Cookie
在设置 cookie 属性的时候设置 Samesite ,限制 cookie 不能作为被第三方使用,从而可以避免被攻击者利用。Samesite 一共有两种模式,一种是严格模式(Samesite=Strict),在严格模式下 cookie 在任何情况下都不可能作为第三方 Cookie 使用,在宽松模式下(Samesite=Lax),cookie 可以被请求是 GET 请求,且会发生页面跳转的请求所使用。
CSRF Token
CSRF攻击之所以能够成功,是因为服务器误把攻击者发送的请求当成了用户自己的请求。那么我们可以要求所有的用户请求都携带一个CSRF攻击者无法获取到的Token(Token是随机生成的,通过加密算法对数据进行加密,一般Token都包括随机字符串和时间戳的组合) 。服务器通过校验请求是否携带正确的Token(解密Token,对比加密字符串以及时间戳,如果加密字符串一致且时间未过期,那么这个Token就是有效的),来把正常的请求和攻击的请求区分开,也可以防范CSRF的攻击。
缺点是需要给网站中的所有请求都添加上这个 token,操作比较繁琐。还有一个问题是一般不会只有一台网站服务器,如果请求经过负载平衡转移到了其他的服务器,但是这个服务器的 session 中没有保留这个 token 的话(Session默认存储在单机服务器内存中,因此在分布式环境下同一个用户发送的多次HTTP请求可能会先后落到不同的服务器上,导致后面发起的HTTP请求无法拿到之前的HTTP请求存储在服务器中的Session数据,从而使得Session机制在分布式环境下失效),就没有办法验证了。
这种情况可以通过改变 token 的构建方式来解决,如采用Encrypted Token Pattern方式,这种方法的Token通常是使用UserID、时间戳和随机数,通过加密的方法生成的一个计算出来的结果,而非随机生成的字符串。这样在校验时无需再去读取存储的Token,只用再次计算一次即可。token解密成功之后,服务器可以访问解析值,Token中包含的UserID和时间戳将会被拿来被验证有效性,将UserID与当前登录的UserID进行比较,并将时间戳与当前时间进行比较。
双重Cookie验证
因为攻击者只能利用 cookie,但是不能拿到 Cookie ,所以服务器可以在用户访问网站页面时,向请求域名注入一个Cookie,内容为随机字符串,然后当用户再次向服务器发送请求的时候,从 cookie 中取出这个字符串,添加到 URL 参数中,服务器通过对 cookie 中的数据和参数中的数据进行比较,来进行验证。缺点是如果网站存在 XSS 漏洞的,那么这种方式会失效,同时这种方式不能做到子域名的隔离。
验证码
CSRF 攻击往往是在用户不知情的情况下构造了网络请求。而验证码会强制用户必须与应用进行交互,才能完成最终请求。
XSS与CSRF区别
- XSS是利用合法用户获取其信息,而CSRF是伪造成合法用户发起请求
DDoS
概念
DoS(Denial of Service),即拒绝服务,意思是通过某种方式(构造特定请求),导致服务器资源被显著消耗,来不及响应更多请求,导致请求挤压,进而产生雪崩效应。
而DDoS(Distributed Denial of Service),即分布式拒绝服务,可以理解成大量设备利用大量的请求造成资源过载,导致服务不可用。
常见攻击方式
DDoS攻击常出现在网络层,传输层,表示层和应用层。网络层和传输层的DDoS攻击一般通过模拟大量的报文,如icmp,udp,tcp来让服务器响应,消耗服务器资源,称为基础设施层攻击。表示层和应用层的DDOS攻击则通过模拟应用层的请求,如http让服务器进行响应,称为应用层攻击。
SYN Flood
基础设施层攻击的一种。攻击者利用TCP协议中三次握手的机制,伪造大量的IP地址发送第一次握手的SYN包给服务器,但是由于伪造的IP地址几乎不可能存在,第三次握手无法完成,导致服务器大量端口处于SYN_RECV状态。由于服务器收不到第三次握手的报文,超时重传,重传一定次数后,才会释放连接。服务器这个状态一般称为半连接。服务器每收到一个SYN包都会将连接信息储存到一个队列中,当超过队列长度时,新来的SYN包无法被响应,服务器也就无法响应正常的tcp请求。
HTTP Flood(CC攻击)
应用层攻击的一种。攻击者通过控制大量“肉鸡”(被黑客成功入侵并受远程操纵的主机)或利用从互联网搜寻的大量知名HTTP代理,模拟正常用户给网站发起请求直到该网站拒绝服务为止。大部分网站会通过CDN及分布式缓存来加快服务器端响应,提升网站吞吐量,而这些HTTP请求有意避开这些缓存,需要进行多次DB查询操作或一次请求返回大量数据,加速系统资源消耗,从而拖垮后端业务处理系统,甚至连相关存储与日志收集系统也无法幸免。
防御方式
网络层DDoS 防御
- 限制单 IP 请求频率DoS 防御
- 网络架构上做好优化,采用负载均衡分流
- 防火墙等安全设备上设置禁止 ICMP 包等
- 通过 DDoS 硬件防火墙的数据包规则过滤、数据流指纹检测过滤、及数据包内容定制过滤等技术对异常流量进行清洗过滤
- 采用 ISP 近源清洗,使用电信运营商提供的近源清洗和流量压制,避免全站服务对所有用户彻底无法访问。这是对超过自身带宽储备和自身 DDoS 防御能力之外超大流量的补充性缓解措施
应用层 DDoS 防御
- 优化操作系统的 TCP/IP 栈
- 应用服务器严格限制单个 IP 允许的连接数和 CPU 使用时间
- 编写代码时,尽量实现优化并合理使用缓存技术。尽量让网站静态化,减少不必要的动态查询
- 增加 WAF(Web Application Firewall)设备,即 Web 应用防火墙。Web 应用防火墙是通过执行一系列针对 HTTP / HTTPS 的安全策略来专门为 Web 应用提供保护的一款产品
- 使用 CDN / 云清洗,在攻击发生时,进行云清洗。通常云清洗厂商策略有以下几步:预先设置好网站的 CNAME,将域名指向云清洗厂商的 DNS 服务器;在一般情况下,云清洗厂商的 DNS 仍将穿透 CDN 的回源的请求指向源站,在检测到攻击发生时,域名指向自己的清洗集群,然后再将清洗后的流量回源
- CDN 仅对 Web 类服务有效,针对游戏类 TCP 直连的服务无效。这时可以使用 DNS 引流 + ADS (Anti-DDoS System) 设备来清洗,还有在客户端和服务端通信协议做处理(如:封包加标签,依赖信息对称等)