摘要:XSS 跨站脚本攻击、CSRF 跨站请求伪造、SQL 注入、DDoS 拒绝服务攻击。
目录
[TOC]
一、XSS 跨站脚本攻击
概念
跨站脚本攻击(Cross-Site Scripting, XSS),可以将代码注入到用户浏览的网页上,这种代码包括 HTML 和 JavaScript。
攻击原理
例如有一个论坛网站,攻击者可以在上面发布以下内容:
1 | |
之后该内容可能会被渲染成以下形式:
1 | |
另一个用户浏览了含有这个内容的页面将会跳转到 domain.com 并携带了当前作用域的 Cookie。如果这个论坛网站通过 Cookie 管理用户登录状态,那么攻击者就可以通过这个 Cookie 登录被攻击者的账号了。
危害
- 窃取用户的 Cookie
- 伪造虚假的输入表单骗取个人信息
- 显示伪造的文章或者图片
防范手段
1. 设置 Cookie 为 HttpOnly
设置了 HttpOnly 的 Cookie 可以防止 JavaScript 脚本调用,就无法通过 document.cookie 获取用户 Cookie 信息。
2. 过滤特殊字符
例如将 < 标签转义为 <,将 > 转义为 >,从而避免 HTML 和 Jascript 代码的运行。
- 富文本编辑器允许用户输入 HTML 代码,就不能简单地将
<等字符进行过滤了,极大地提高了 XSS 攻击的可能性。 - 富文本编辑器通常采用 XSS filter 来防范 XSS 攻击,通过定义一些标签白名单或者黑名单,从而不允许有攻击性的 HTML 代码的输入。
以下例子中,form 和 script 等标签都被转义,而 h 和 p 等标签将会保留。
1 | |
1 | |
二、CSRF 跨站请求伪造
概念简介
跨站请求伪造(Cross-site request forgery,CSRF):通过(Cookie)伪造用户请求(让用户误点击非法链接、骗用户的浏览器)去访问曾经认证过的网站,让其以用户的名义执行操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。
-
由于浏览器曾经认证过,登录信息尚未过期,所以被访问的网站会认为是真正的用户操作而去执行。
-
也被称为“
One Click Attack” 或者Session Riding。 -
跨域:只要网络协议、域名、端口中任何一个不相同就是跨域请求。
XSS 对比 CSRF:
- XSS 利用的是用户对指定网站的信任,受信任站点
- CSRF 利用的是网站对用户浏览器的信任。是欺骗用户浏览器,让其以用户的名义执行操作。
攻击原理
过程:
- 客户端与服务端进行交互时,由于http协议本身是无状态协议,所以引入了cookie进行记录客户端身份。
- 在cookie中会存放session id用来识别客户端身份。
- 在跨域的情况下,session id 可能被第三方恶意劫持,通过这个session id 向服务端发起请求时,服务端会认为这个请求是合法的。
假如一家银行用以执行转账操作的 URL 地址如下:
1 | |
那么,恶意攻击者可以在另一个网站上放置如下代码:
1 | |
如果有账户名为 Alice 的用户访问了恶意站点,而她之前刚访问过银行不久,登录信息尚未过期,那么她就会损失 1000 美元。
此外,攻击者也不需要控制放置恶意网址的网站。例如他可以将这种地址藏在论坛,博客等任何用户生成内容的网站中。这意味着如果服务器端没有合适的防御措施的话,用户即使访问熟悉的可信网站也有受攻击的危险。
通过例子能够看出,攻击者并不能通过 CSRF 攻击来直接获取用户的账户控制权,也不能直接窃取用户的任何信息。他们能做到的,是欺骗用户浏览器,让其以用户的名义执行操作。
防范手段
1. 检查 Referer 首部字段
Referer 首部字段位于 HTTP 报文中,用于标识请求来源的地址。检查这个首部字段并要求请求来源的地址在同一个域名下,可以极大的防止 CSRF 攻击。
- 局限性:因其完全依赖浏览器发送正确的 Referer 字段。虽然 HTTP 协议对此字段的内容有明确的规定,但并无法保证来访的浏览器的具体实现,亦无法保证浏览器没有安全漏洞影响到此字段。并且也存在攻击者攻击某些浏览器,篡改其 Referer 字段的可能。
2. 添加校验 Token
在访问敏感数据请求时,要求用户浏览器提供不保存在 Cookie 中、并且攻击者无法伪造的数据作为校验。例如服务器生成随机数并附加在表单中,并要求客户端传回这个随机数。
3. 输入验证码
因为 CSRF 攻击是在用户无意识的情况下发生的,所以要求用户输入验证码可以让用户知道自己正在做的操作。
三、SQL 注入攻击
概念
服务器上的数据库运行非法的 SQL 语句,主要通过拼接来完成。
攻击原理
常见的SQL 注入方式:通过网页输入框(<input> 、<textarea> 标签等)将恶意 SQL 代码提交给服务器。将 userName 参数拼接到 SQL 语句中,从而构建 SELECT 查询,从数据库中获取当前用户的所有信息。
例如一个网站登录验证的 SQL 查询代码为:
1 | |
如果填入以下内容:
1 | |
那么 SQL 查询字符串为:
1 | |
此时无需验证通过就能执行以下查询:
1 | |
防范手段
1. 使用参数化查询
SQL注入发生在编译过程中,因为注入了某些特殊字符,最后被编译成了恶意的执行操作;
Java 中的 PreparedStatement 是预先编译的 SQL 语句,可以传入适当参数并且多次执行。由于没有拼接的过程,因此可以防止 SQL 注入的发生。
-
预编译完成后,SQL 的结构已经固定,即便用户输入非法参数,也不会对 SQL 的结构产生影响,从而避免了潜在的安全风险。
-
传参用参数占位符
#{},尽量避免用变量占位符${};
1 | |
2. 数据验证
服务端数据验证是在数据提交到服务器上后再验证。客户端数据验证是在数据发送到服务器前,在浏览器上完成验证,包括 HTML5 内置约束验证、JavaScript 自定义表单验证、CSS 伪类选择器。
1 | |
3. 检测用户输入
永远不要信任用户提供的数据,仅在校验通过后才将数据提交给数据库。如:
- 在页面输入参数时进行字符串检测;
- 提交时进行参数检查、用正则表达式过滤参数中的特殊符号等;
- 单引号转换:将传入的参数中的单引号转换为连续两个单引号,PHP 中的 Magic quote 可以完成这个功能。
- Spring Boot 整合
Hibenate-Validator框架; - 用户输入的 SQL 参数严格使用参数绑定或 METADATA 字段值限定,禁止字符串拼接 SQL 访问数据库。
4. Web 防火墙
Web 防火墙可检测和阻止最基本的 SQL 注入;
四、DDoS 拒绝服务攻击
拒绝服务攻击(denial-of-service attack,DoS),亦称洪水攻击,其目的在于使目标电脑的网络或系统资源耗尽,使服务暂时中断或停止,导致其正常用户无法访问。
分布式拒绝服务攻击(distributed denial-of-service attack,DDoS),指攻击者使用两个或以上被攻陷的电脑作为“僵尸”向特定的目标发动“拒绝服务”式攻击。