不是所有 Web 开发者都有安全的概 uploads 念,特别是前端开发者基本上不太关心 Web 安全,认为那是后端开发者应该关注的。其实对于 Web 安全前后端没有必要分那么清。相对而言,前端代码很容易暴露客户端上,相对没那么安全,所以原则上是后端为主,前端为辅。
通常我们所说的 Web 安全问题有三个详解 SQL 注入、XSS 攻击和 CSRF 攻击。
SQL 注入
SQL 注入,顾名思义就是通过注入 SQL 命令来进行攻击,更确切地说攻击者把 SQL 命令插入到 web 表单或请求参数的查询字符串里面提交给服务器,从而让服务器执行编写的恶意的 SQL 命令。
对于 web 开发者来说,SQL 注入已然是非常熟悉的,而且 SQL 注入已经生存了 10 多年,目前已经有很成熟的防范方法,所以目前的 web 应用都很少会存在漏洞允许进行 SQL 注入攻击。 除非是入门开发人员,在开发的时候仍使用旧的技术去实现(比如 Java 的 Statement 和 PreparedStatement)。
产生的原因
从上面可知,SQL 注入是通过让服务器执行了恶意的 SQL 命令从而进行攻击的,那么主要问题就出在于服务器是如何生成 SQL 语句的。其实绝大多数拥有 SQL 注入漏洞的 Web 系统,在生成 SQL 语句的时候,采用的是拼接字符串的方式,并且没有对要组装成 SQL 语句的参数进行检验和过滤。
实例
看下面 PHP 代码:
[php]
$user = mysql_query('SELECT * FROM USERS WHERE UserName="'.$_GET['user'].'"');
[/php]那么当请求中 user 参数为 ";DROP TABLE USERS 时,合成的 SQL 语句是:
[php]
SELECT * FROM USERS WHERE UserName="";DROP TABLE USERS"
[/php]这里产生什么结果就不需要解释了吧 :) 另外,通过 SQL 注入,往往还能拿到系统权限。
如何防护
推荐所有 SQL 语句都使用参数化查询,通常使用成熟一些的后台框架都能避免这个问题。
XSS 攻击
XSS,全名:cross-site scripting(跨站点脚本),是当前 web 应用中最危险和最普遍的漏洞之一。攻击者尝试注入恶意脚本代码到受信任的网站上执行恶意操作,用户使用浏览器浏览含有恶意脚本页面时,会执行该段恶意脚本。它与 SQL 注入很类似,同样是通过注入恶意指令来进行攻击。但 SQL 注入是在服务器端上执行的,而 XSS 攻击是在客户端上执行的,这点是他们本质区别。
分类
XSS 攻击的分类没有标准,但普遍分为三类:
- 反射型 XSS(非持久性跨站攻击)
- 存储型 XSS(持久性跨站攻击
- DOM Based XSS(基于 dom 的跨站点脚本攻击)
下面将直接以一些小例子来说明以上三种类别的 XSS 攻击分别是怎样的。
反射型 XSS(非持久性跨站攻击)
一般是利用网站某些页面会直接输出请求参数的特性,通过在 URL 的请求参数包含恶意脚本,导致用户打开该 URL 的时候,执行恶意脚本。
其攻击过程如下:
用户 A
经常浏览某网站。用户 A
使用用户名/密码进行登录该站点,并存储敏感信息(比如银行帐户信息)。黑客 B
发现某站点包含反射性 XSS 漏洞,于是编写一个利用漏洞的 URL,并将其冒充为来自某站点的邮件发送给 A
。
用户 A
在登录到该信任站点后,浏览黑客 B
提供的 URL。嵌入到 URL 中的恶意脚本在用户 A
的浏览器中执行,就像它直接来自信任站点的服务器一样。此脚本盗窃敏感信息(授权、信用卡、帐号信息等)然后在用户 A
完全不知情的情况下将这些信息发送到黑客 B
的 Web 站点。
存储型 XSS(持久性跨站攻击)
该种类型的攻击一般是通过表单输入(比如发布文章、回复评论等功能中)插入一些恶意脚本,并且保存到数据库,待其他用户加载对应的页面的时候,该段脚本就会被加载并执行。
与反射型 XSS 相比,该类的攻击更具有危害性,因为它影响的不只是一个用户,而是大量用户,而且该种类型还可进行蠕虫传播。其攻击过程如下:
某网站允许用户发布信息/浏览已发布的信息。黑客注意到该站点具有存储型 XSS,于是发布一个热点信息,吸引其它用户纷纷阅读。某网站管理员或任何的其他用户浏览该信息,其会话 cookies
或者其它信息将被黑客盗走。
DOM Based XSS(基于 Dom 的跨站点脚本)
基于 DOM 的跨站点脚本与前面两种类型有什么区别呢?其实它注入的方式是基于前面两种类型的方式的,只不过是注入的脚本是通过改变 DOM 来实施的。采用该种方式有一个好处就是从源代码中不易被发现而已。
产生的原因
主要原因与 SQL 注入很类似,都是由于开发人员没有对用户输入进行编码和过滤。另一个原因是,这种攻击方法有很多变体,要设计出一个能完全防御的 XSS 过滤器是非常困难的。
如何防护
基于上面漏洞产生的原因,我们若要想防御该种攻击,就需要从源头抓起(用户输入),制定一套合理且安全的 XSS 过滤规则。
- 对 HTML 标签及一些特殊符号进行转义
该种方法是一种非常简单的过滤方法,仅仅是通过转义的方式将一些 HTML 标签和属性转义,比如 <
转义成 <, 这样脚本就运行不了。当然简单的过滤方式也就代表很容易就会被绕过。
另外如果需要使用含有富文本的功能时,使用这样的过滤就会使富文本失去作用。
- 使用白名单、黑名单的方式进行过滤
白名单、黑名单顾名思义是要定义哪些东西是可通过的,哪些东西不可通过。比如常见 <span>
、<p>
等标签就可通过,不可通过的比如 javascript
、<a>
、<script>
、<iframe>
、onload
等等一些属性,将其进行转义。
当然使用该种方法也有自身的缺点,你并不可能穷举出所有元素,也可能会某些元素在黑名单内,但在某些情况它是需要使用的,这就需要我们在设计 XSS 过滤器的时候权衡好,取最合理最适合需求的设计。
XSS 攻击作为 Web 业务的最大威胁之一,不仅危害 Web 业务本身,对访问 Web 业务的用户也会带来直接的影响,如何防范和阻止 XSS 攻击,保障 Web 站点的业务安全,是定位于业务威胁防御的入侵防御产品的本职工作。
CSRF 攻击
CSRF(跨站域请求伪造),全名:Cross site Request Forgery。尽管听起来像跨站脚本(XSS),但它与 XSS 非常不同,XSS 利用站点信任用户,而 CSRF 则利用用户信任站点。与 XSS 攻击相比,CSRF 攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比 XSS 更具危险性。一般的攻击方式是,通过请求伪造盗取用户的 cookie 信息,进而进行操作。其攻击过程如下:
- 首先用户
A
请求登陆了服务器B
,这时服务器B
响应了用户A
,并且会返回唯一标识的该用户的cookie
信息。 - 用户
A
在未退出服务器B
时,访问了带有恶意脚本的服务器C
,服务器C
响应给用户A
一个恶意页面,并且通过恶意脚本伪装用户A
向服务器B
发送请求,此时服务器B
误以为是用户A
请求,故响应并返回了用户 A 的cookie
信息。 - 服务器
C
收到用户A
与 服务器B
的 cookie 信息后,保存起来,并利用该信息伪装成用户A
去访问服务器B
,再进行相应的破坏。
产生的原因
其主要原因是服务 B
没有对请求的发起源进行合理的检验,即不加分析地认为请求者一定是正常的用户,就响应了用户信息给非法分子。
如何防护
- 验证 HTTP Referer 的值
- 使用请求令牌
验证 HTTP Referer
熟悉 HTTP 协议的人都知道,HTTP 的头部 有一个 Referer
信息的字段,它记录着该次 HTTP 请求的来源地址(即它从哪里来的)。
既然 CSRF 攻击伪造的请求是从服务器C
发送过来的,那么我们就禁止跨域访问,在服务器端增加过滤器的过滤,过滤掉那些不是从本服务器B
发出的请求,这样可以在一定程度上避免 CSRF 攻击。
使用请求令牌
该种方式是参考同步令牌所设计的,同步令牌是用于防止表单重复提交的场景。
请求令牌的工作方式:
- 用户
A
访问服务器B
- 服务器
B
以某种随机生成策略生成随机字符串,并作为token
(令牌)保存在session
里面,然后夹带着响应返回给用户,并以隐藏域的形式保存在页面中 - 用户每次请求都会夹带着
token
反馈给服务器 - 服务器接收到每次请求,都会先进行
token
验证,若令牌验证不通过,则认为该次请求是非法的,拒绝响应。
由于 CSRF 是通过在服务器 C
上伪造请求的方式来访问服务器 B
,所以它是获取不了页面中的 token
字符串,所以在一定程度上是能防御的。
CSRF 攻击是一种请求伪造的攻击方式,它利用的是服务器不能识别用户的类型从而盗取用户的信息来攻击。因此要防御该种攻击应该从服务器端着手,增强服务器的识别能力,设计良好的防御机制。
评论 (0)