网络安全
什么是CSRF
CSRF(Cross-site request forgey)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中向被攻击者网站发送跨站请求。利用受害者在攻击网站已经获取的注册凭证,绕过后台用户验证,达到冒充用户对被攻击的网站执行某种操作的目的。
一个典型的CSRF攻击过程
- 受害者登录网站
a.com,并保留了登录凭证(Cookie)
- 攻击者引诱受害者访问了
b.com
b.com向a.com发送了一个跨站请求:a.com/act=xxx,浏览器会默认携带a.com的Cookie
a.com服务器接收到请求后,对请求进行验证,并确认受害者的凭证,误以为是受害者自己发送的请求
a.com接收了以受害者名义发送的act=xx
- 攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让a.com执行了自己定义的操作 CSRF
CSRF的特点
- 攻击发生在
第三方网站,被攻击网站无法阻止攻击发生
- 攻击利用受害者在被攻击网站的
登录凭证(整个过程没有获取到受害者的登录凭证,,只是冒用)
- 跨站请求各种方式:图片URL、超链接、CORS、Form提交等等
防护策略
-
阻止不明外域的访问
-
同源检测,CSRF大多来自第三方网站,我们直接禁止外域对我们发起请求 如何判断请求是否来自外域? 在HTTP协议中,每一个异步请求都会携带两个Header,用于标记来源域名:-
Origin Header对应请求头Origin字段,标识请求来源地址 。请求来源不包含path和query- 不存在Origin 字段的情况:1. IE11同源策略:不会在跨站CORS上添加Origin字段,Referer头是唯一标识 2. 302重定向,因为Origin重定向可能被认为是其他来源的敏感信息,因此浏览器不想Origin泄露到新服务器上
-
Referer Header对应请求头Referer字段 HTTP请求的来源地址。对于Ajax请求,图片和script等资源请求,Referer为发起请求的页面地址;对于页面跳转,Referer为打开页面历史记录的前一个页面地址。Referer是由浏览器提供的,可能不安全,攻击者可以隐藏、甚至修改自己请求的Referer Referer Policy草案:tech.meituan.com/2018/10/11/… 设置Referer Policy: 比如设置成same-origin,对于同源的链接和引用,会发送Referer,referer 值为Host不带Path。如果是跨域访问,则不设置Referer 设置Referer
-
-
SameSite Cookie: 有两个属性Strict和Lax
Samesite=Strict, 严格模式,表明这个Cookie在任何情况下都不可以作为第三方Cookie,绝无例外。 比如b.com设置了``` Set-Cookie:foo=1;Samesite=Strict Set-Cookie:bar=2;Samesite=Lax Set-Cookie:baz=3 ```我们在
a.com下发送对b.com的任意请求,foo这个cookie都不会被包含在cookie请求头中,但bar会 。Samesite=Lax, 宽松模式,比Strict放宽一点限制:加入这个请求(会改变了当前页面或打 开了新页面),且同时是GET请求,则这个Cookie可以作为第三方请求。 同样:Set-Cookie:foo=1;Samesite=Strict Set-Cookie:bar=2;Samesite=Lax Set-Cookie:baz=3 -
如果a.com网站是点击链接(GET请求),foo不会包含在Cookie请求头中,但是bar和baz会 如果a.com网站发起对b.com的异步请求,或者页面跳转是通过表单POST提交的,bar不会发送.
提交时要求附加本域才能获取的信息
-
CSRF Token:CSRF产生的原因之一是服务器误把攻击者的请求当成了用户的请求,那我们可以要求所有的用户请求都携带一个CSRF攻击者无法获取到的Token。服务器通过校验请求是否携带正确的Token,来把正常的请求和攻击的请求分开-
原理:三个步骤
将CSRF Token输出到页面中。服务器需要给这个用户生成一个Token,该Token通过加密算法对数据进行加密,一般Token都包括随机字符串和时间戳的组合,Token就不能放Cookie中,最好存在服务器的Session中,之后每次页面加载时,用JS遍历整个DOM树,对所有的a和form标签加入Token(对于页面加载后动态生成的HTML代码),需要我们手动加入页面提交的请求携带这个Token。GET请求可以拼接到URL后面,POST请求可以设置一个<input type="hidden" name="csrftoken" value="token">标签 3.服务器验证Token是否正确。服务器对Token进行解密,对比加密字符串以及时间戳,如果加密字符串一致且时间未过期,token有效。
-
分布式校验token 在大型网站中,使用session存储CSRF Token会带来很大的压力(session默认存储在单及服务器内存中),在分布式环境下同一个用户发送的多次HTTP请求可能会先后落在不同的服务器上,导致后面发起的HTTP请求无法拿到之前HTTP请求存储在服务器中的Session数据,使得session机制在分布式环境下失效,
因此分布式集群中CSRF Token需要存储在Redis之类的公共存储空间使用Session存储,读取和验证CSRF Token会引起比较大的复杂度和性能问题,目前很多网站采用Encryptyed Token Pattern方式。这种方法的Token是一个计算出来的结果,而非随机生成的字符串.这样在校验时无需再去读取存储的Token,只用再计算一次即可。 Token值通常使用UserID、时间戳和随机数,通过加密的方法生成
双重Cookie验证就是在提交前先用js读取用于验证的cookie值加入到提交字段,这样验证字段有两份,一份在cookie中,一份在POST或者URL中。那CSRF只能让请求中带有Cookie但是不能读取cookie加入到POST或URL中
优点:
- 无需使用session,适用卖弄更广,易于实施
- Tokens存储于客户端中,不会给服务器带来压力
- 相对于Token,实施成本低,可以在前后端设置统一拦截校验,无需一个个接口或一个个页面添加 缺点:
- Cookie中添加了额外的字段
- 如果有XSS攻击,供给者可以注入Cookie
- 难以做到子域名的隔离
- Cookie传输安全,采用这种防御方式最好确保用到整个HTTPS的方式
XXS攻击
Cross-Site Scripting(跨站脚本攻击,简称XSS),是一种恶意代码注入攻击。供给者通过在目标网站注入恶意脚本,使之在用户浏览器上运行。利用这些恶意脚本,供给者可获取用户的敏感信息,如Cookie、SessionId等,进而危害数据安全。
XSS本质上就是 恶意代码未经过滤,与网站正常代码混在一起;浏览器无法辨别哪些脚本是可信的,导致恶意脚本运行,其来源:
- 来自用户的
UGC信息
- 来自第三方的链接
- URL参数
- POST参数
- Referer (可能来自不可信来源)
- Cookie(可能来自其他子域注入)
XSS的分类
三种:存储型、反射型和DON型
存储型XSS攻击步骤:
- 攻击者将恶意代码提交到目标网站的
数据库中
- 用户打开目标网站时,网站服务端 将 恶意代码从数据库取出,拼接在HTML中返回给浏览器
- 用户浏览器接受到响应后解析执行,混在 其中 的恶意代码 也被执行
- 恶意代码窃取用户数据发送到 攻击者的网站 ,或者冒充用户行为,调用目标网站接口执行 攻击者执行操作 这种攻击常见于 带有用户保存数据的网站功能,如 论坛 、商品评论 、 用户私信等
反射型XSS攻击步骤:
- 攻击者构造出
特殊的URL,其中包括恶意代码
- 用户访问恶意代码URL时 ,网站服务将 恶意代码从URL中取出,拼接在HTML中返回浏览器
- 用户浏览器接收到响应后执行, 混在其中的恶意代码也被执行
- 恶意代码窃取用户数据发送到 攻击者的网站 ,或者冒充用户行为,调用目标网站接口执行 攻击者执行操作常见于通过URL传递参数的功能,如网站搜索、跳转等 与存储型XSS的区别:存储型XSS的恶意代码存在数据库里,反射型XSS的恶意代码存在URL里
DOM型XSS的攻击步骤:
- 攻击者构造出 特殊的URL , 其中包含恶意代码
- 用户打开带有恶意代码的URL
- 用户浏览器 接收到响应后解析执行 , 前端js取出URL中的恶意代码并执行
- 恶意代码窃取用户数据发送到 攻击者的网站 ,或者冒充用户行为,调用目标网站接口执行 攻击者执行操作
DOM型与前两种的区别:DOM型XSS攻击中,取出和执行恶意代码由浏览器完成,属于前端JS自身的安全漏洞,其他两种XSS都属于服务端的安全漏洞
预防XSS攻击
-
预防存储型XSS和反射型XSS攻击存储型和反射型XSS都是服务端取出恶意代码后,插入到响应端HTML里,攻击者编写的 “ 数据” 被内嵌到“代码”中,被浏览器所执行。 预防:-
改成纯前端渲染,把代码和数据分隔开来纯前端渲染的过程:- 浏览器加载一个HTML页面,该页面不包含任何数据
- 然后浏览器执行HTML中的js
- js通过Ajax加载业务数据,调用DOM API更新到页面上 纯前端渲染可 识别哪些是文本
.innerText哪些是.setAttribute属性,哪些是.style样式等。但是需要避免DOM型XSS漏洞(onLoad事件和href中的javascript:等)
-
对 HTML 做充分的转义,可以使用合适的转义库ejs
-
-
预防DOM型XSS攻击
- 使用
.innerHTML、outerHTML、document.write()时需要小心,不要把不可信的数据作为HTML插入到页面,而应尽量使用.textContent、setAttribute() - 使用
Vue/React技术栈,并且不使用v-html/dangerouslySetInnerHTML,就在前端render阶段避免使用innerHTML、outerHTML的XSS隐患 - DOM中的内联事件监听器,如
location、onclick、onerror、onload、onmouseover等,<a>标签的href属性,js的eval()、setTimeout()、setTimeout等,都能把字符串作为代码运行。如果把不可信的数据拼接到字符串中传递给这些API,很容易产生安全隐患。
- 使用
JSONP可能产生的安全隐患
可能存在CSRF攻击
当某个网站通过JSONP的方式来传递用户敏感信息时,攻击者构造恶意的JSONP调用页面,诱导被攻击者访问来达到截取用户敏感信息的目的。
如下攻击代码:
<script>
function Hack(){
alert(v.username)
}
</script>
<script src="http://js.login.cn/?o=ss0&m=info&func=Hack"></script>
当被攻击者在登陆js网站的情况下访问了该网页时,那么用户的隐私数据(如用户名,邮箱等)可能被攻击者劫持。
解决方案:Referer过滤
可能存在XSS攻击
使用Content-Type:application/javascript造成HTML根据js解析文件,造成XSS
解决方案:严格使用Content-Type: application/json
HTTPS中间人攻击
中间人攻击:即(Main-in-the-middle attack|MITM) ,就是中间人会在消息发出方和接收方之间拦截双方通讯,并进行信息篡改。
常见的HTTPS中间人攻击,首先需要结合ARP(IP地址->Mac地址)、DNS欺骗技术进行拦截。
- SSL证书欺骗攻击
通过ARP欺骗、DNS劫持甚至网关劫持等,将客户端的访问重定向到攻击者的机器,让客户端机器与攻击者机器建立HTTPS(使用伪造证书), 而攻击者再跟服务器建立连接。 虽然用户在浏览器看到的链接是相同域名的网站,但浏览器会提示证书不可信, 用户不点击继续浏览就能避免被劫持。
- SSL剥离攻击(SSLStrip)
SSL剥离,即将HTTPS连接降级到HTTP连接。该方式主要是利用用户并不会每次都直接输入https://xxx.xxx.com来访问网站,或则有些网站并非全网HTTPS,而是只是在需要进行敏感数据传输时才使用HTTPS,中间人通过劫持了客户端与服务端的HTTP会话后,将HTTP页面所有的https://超链接都换成http://``用户在点击链接时,使用HTTP协议进行访问。所以攻击者可以伪造响应数据发送给客户端。服务端在配置HTTPS服务时,加上HTTP Strict Transport Security`配置项
- 针对SSL算法进行攻击 OpenSSL漏洞
防范措施:
-
不要随意连入公共场所的WIFI,或者使用未知代理服务器
-
不要安装不可信或突然出现的描述文件,信任伪造的证书
-
客户端对服务器进行单独对比校验,确认证书不是伪造的。
SYN攻击是什么?
是一种典型的DOS/DDOS攻击
服务端的资源分配是在第二次握手是分配的,而客户端的资源是在完成第三次报文握手时分配的,所以服务器容易收到SYN攻击。SYN攻击就是**Client在短时间内伪造大量不存在的IP地址**,并向服务器不断的发送SYN包,并等客户端回应。但由于源地址不存在,服务器不断的重发超时,这些伪SYN包长时间的占用未连接队列,导致正常的SYN请求因为队列满而被抛弃,从而引起网络拥塞甚至系统瘫痪。
如何检验?当你在服务器上看到大量半连接状态时+IP地址随机,基本上可以断定是SYN攻击。Linux/Uinx上可以使用netstat -n -p TCP | grep SYN_RECV进行检测
常见防御SYN攻击的方法:
- 缩短超时(SYN Timeout)时间
- 增加最大半连接数
- 过滤网防护
内容来源: