2021-03-25

web端常见网络攻击有哪些?如何防范?

一、 XSS 攻击

XSS 攻击全称跨站脚本攻击(Cross-Site Scripting),简单的说就是攻击者通过在目标网站上注入恶意脚本并运行,获取用户的敏感信息如 CookieSessionID 等,影响网站与用户数据安全。

XSS 攻击更偏向前端的范畴,但后端在保存数据的时候也需要对数据进行安全过滤。

攻击原理: 当攻击者通过某种方式向浏览器页面注入了恶意代码,并且浏览器执行了这些代码。

比如: 在一个文章应用中(如微信文章),攻击者在文章编辑后台通过注入 script 标签及 js 代码,后端未加过滤就保存到数据库,前端渲染文章详情的时候也未加过滤,这就会让这段 js 代码执行,引起 XSS 攻击。

解决方案:

一个基本的思路是渲染前端页面(不管是客户端渲染还是服务器端渲染)或者动态插入 HTML 片段时,任何数据都不可信任,都要先做 HTML 过滤,然后再渲染。 同时,对于站内各种输入框,甚至会引起数据库变化的接口请求中,也默认不可信。

二、 SQL注入

SQL 注入就是通过给 web 应用接口传入一些特殊字符,达到欺骗服务器执行恶意的 SQL 命令。

SQL 注入漏洞属于后端的范畴,但前端也可做体验上的优化。

攻击原理: 当使用外部不可信任的数据作为参数进行数据库的增、删、改、查时,如果未对外部数据进行过滤,就会产生 SQL 注入漏洞。

比如:

name = "外部输入名称";
sql = "select * from users where name=" + name;

上面的 SQL 语句目的是通过用户输入的用户名查找用户信息,因为由于 SQL 语句是直接拼接的,也没有进行过滤,所以,当用户输入 '' or '1'='1' 时,这个语句的功能就是搜索 users 全表的记录。

select * from users where name='' or '1'='1';

解决方案:

具体的解决方案很多,但大部分都是基于一点:不信任任何外部输入。 所以,一般来说,我们会和XSS一块做处理,只要对任何外部输入都进行过滤,然后再进行数据库的增、删、改、查。就可以从源头杜绝注入类的攻击。 此外,适当的权限控制、不曝露必要的安全信息和日志也有助于预防 SQL 注入漏洞。

三、CSRF 攻击

CSRF 攻击全称跨站请求伪造(Cross-site Request Forgery),简单的说就是攻击者盗用了你的身份,以你的名义发送恶意请求。

攻击原理: 一个典型的 CSRF 攻击有着如下的流程:

受害者登录 a.com,并保留了登录凭证(Cookie) 攻击者引诱受害者访问了 b.com b.com 向 a.com 发送了一个请求:a.com/act=xx(浏览器会默认携带 a.com 的 Cookie) a.com 接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求 a.com 以受害者的名义执行了 act=xx 攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让 a.com 执行了自己定义的操作

解决方案:

CSRF的两个特点:

  • CSRF(通常)发生在第三方域名。
  • CSRF攻击者不能获取到Cookie等信息,只是使用。

防止 CSRF 攻击需要在服务器端入手,基本的思路是能正确识别是否是用户发起的请求。

方案1:同源检测

既然CSRF大多来自第三方网站,那么我们就直接禁止外域(或者不受信任的域名)对我们发起请求。

那么问题来了,我们如何判断请求是否来自外域呢?

在HTTP协议中,每一个异步请求都会携带两个Header,用于标记来源域名:

  • Origin Header
  • Referer Header

a. 使用Origin Header确定来源域名

在部分与CSRF有关的请求中,请求的Header中会携带Origin字段。字段内包含请求的域名(不包含path及query)。

如果Origin存在,那么直接使用Origin中的字段确认来源域名就可以。

但是Origin在以下两种情况下并不存在:

IE11同源策略: IE 11 不会在跨站CORS请求上添加Origin标头,Referer头将仍然是唯一的标识。最根本原因是因为IE 11对同源的定义和其他浏览器有不同,有两个主要的区别。

302重定向: 在302重定向之后Origin不包含在重定向的请求中,因为Origin可能会被认为是其他来源的敏感信息。对于302重定向的情况来说都是定向到新的服务器上的URL,因此浏览器不想将Origin泄漏到新的服务器上。

b. 使用Referer Header确定来源域名

根据HTTP协议,在HTTP头中有一个字段叫Referer,记录了该HTTP请求的来源地址。 对于Ajax请求,图片和script等资源请求,Referer为发起请求的页面地址。对于页面跳转,Referer为打开页面历史记录的前一个页面地址。因此我们使用Referer中链接的Origin部分可以得知请求的来源域名。

这种方法并非万无一失,Referer的值是由浏览器提供的,虽然HTTP协议上有明确的要求,但是每个浏览器对于Referer的具体实现可能有差别,并不能保证浏览器自身没有安全漏洞。使用验证 Referer 值的方法,就是把安全性都依赖于第三方(即浏览器)来保障,从理论上来讲,这样并不是很安全。在部分情况下,攻击者可以隐藏,甚至修改自己请求的Referer。

设置Referrer Policy的方法有三种:

  • CSP设置
  • 页面头部增加meta标签
  • a标签增加referrerpolicy属性

方案2:csrf token

前面讲到CSRF的另一个特征是,攻击者无法直接窃取到用户的信息(Cookie,Header,网站内容等),仅仅是冒用Cookie中的信息。

而CSRF攻击之所以能够成功,是因为服务器误把攻击者发送的请求当成了用户自己的请求。那么我们可以要求所有的用户请求都携带一个CSRF攻击者无法获取到的Token。服务器通过校验请求是否携带正确的Token,来把正常的请求和攻击的请求区分开,也可以防范CSRF的攻击。

CSRF Token的防护策略分为三个步骤:

1. 将CSRF Token输出到页面中

首先,用户打开页面的时候,服务器需要给这个用户生成一个Token,该Token通过加密算法对数据进行加密,一般Token都包括随机字符串和时间戳的组合,显然在提交时Token不能再放在Cookie中了,否则又会被攻击者冒用。因此,为了安全起见Token最好还是存在服务器的Session中,之后在每次页面加载时,使用JS遍历整个DOM树,对于DOM中所有的a和form标签后加入Token。这样可以解决大部分的请求,但是对于在页面加载之后动态生成的HTML代码,这种方法就没有作用,还需要程序员在编码时手动添加Token。

2. 页面提交的请求携带这个Token

3. 服务器验证Token是否正确

当用户从客户端得到了Token,再次提交给服务器的时候,服务器需要判断Token的有效性,验证过程是先解密Token,对比加密字符串以及时间戳,如果加密字符串一致且时间未过期,那么这个Token就是有效的。

这种方法要比之前检查Referer或者Origin要安全一些,Token可以在产生并放于Session之中,然后在每次请求时把Token从Session中拿出,与请求中的Token进行比对,但这种方法的比较麻烦的在于如何把Token以参数的形式加入请求。

方案3:Samesite Cookie属性

防止CSRF攻击的办法已经有上面的预防措施。为了从源头上解决这个问题,Google起草了一份草案来改进HTTP协议,那就是为Set-Cookie响应头新增Samesite属性,它用来标明这个 Cookie是个“同站 Cookie”,同站Cookie只能作为第一方Cookie,不能作为第三方Cookie。

如果SamesiteCookie被设置为Strict,浏览器在任何跨域请求中都不会携带Cookie,新标签重新打开也不携带,所以说CSRF攻击基本没有机会。

但是跳转子域名或者是新标签重新打开刚登陆的网站,之前的Cookie都不会存在。尤其是有登录的网站,那么我们新打开一个标签进入,或者跳转到子域名的网站,都需要重新登录。对于用户来讲,可能体验不会很好。

如果SamesiteCookie被设置为Lax,那么其他网站通过页面跳转过来的时候可以使用Cookie,可以保障外域连接打开页面时用户的登录状态。但相应的,其安全性也比较低。

另外一个问题是Samesite的兼容性不是很好,现阶段除了从新版Chrome和Firefox支持以外,Safari以及iOS Safari都还不支持,现阶段看来暂时还不能普及。

而且,SamesiteCookie目前有一个致命的缺陷:不支持子域。例如,种在topic.a.com下的Cookie,并不能使用a.com下种植的SamesiteCookie。这就导致了当我们网站有多个子域名时,不能使用SamesiteCookie在主域名存储用户登录信息。每个子域名都需要用户重新登录一次。

总之,SamesiteCookie是一个可能替代同源验证的方案,但目前还并不成熟,其应用场景有待观望。

四、DDoS 攻击

DoS 攻击全称拒绝服务(Denial of Service),简单的说就是让一个公开网站无法访问,而 DDoS 攻击(分布式拒绝服务 Distributed Denial of Service)是 DoS 的升级版。

这个就完全属于后端和运维的范畴了。

攻击原理:

攻击者不断地提出服务请求,让合法用户的请求无法及时处理,这就是 DoS 攻击。 攻击者使用多台计算机或者计算机集群进行 DoS 攻击,就是 DDoS 攻击。

解决方案: 防止 DDoS 攻击的基本思路是限流,限制单个用户的流量(包括 IP 等)。

WRITTEN BY

lidong

鄂ICP备20003892号Copyright © 2017-2023 leedong.cn

ABOUT ME

Hello,这里是「我的心情永不立冬」
一个想到什么就做什么的个人站点,所有内容纯主观、有偏见