[ day11.前端之Web攻击概念篇| 青训营笔记]

135 阅读10分钟

这是我参与「第五届青训营 」笔记创作活动的第11天。

今天主要记录了学习Web攻击的方式和一些简单的概念等。

和大家分享一下。

什么是web攻击?

Web攻击(WebAttack)是针对用户上网行为或者网站服务器等设备进行攻击的行为。比如:植入恶意代码,修改网站权限,获取网站用户隐私信息等。

Web安全的考虑是Web业务者工作中重要的组成部分,也许你对所有的安全问题都有一定的认识,但最主要的还是在编码设计的过程中时刻绷紧安全那根弦,需要反复推敲每个实现细节,安全无小事。

确保Web应用程序安全十分重要,即使是代码中很小的 bug 也有可能导致隐私信息被泄露。

常见的Web攻击方式:

  • XSS (Cross Site Scripting) 跨站脚本攻击
  • CSRF(Cross-site request forgery)跨站请求伪造
  • SQL注入攻击

XSS

XSS 的原理是恶意攻击者往 Web 页面里插入恶意可执行网页脚本代码,当用户浏览该页之时,嵌入其中 Web 里面的脚本代码会被执行,从而可以达到攻击者盗取用户信息或其他侵犯用户安全隐私的目的。

XSS涉及的三方:攻击者,客户端,Web应用。

攻击目标:盗取存储在客户端的cookie或者其他网站用于识别客户端身份的敏感信息。一旦获取到合法用户的信息后,攻击者甚至可以假冒合法用户与网站进行交互。

常见的XSS类型:

非持久型XSS

也称为反射型XSS漏洞。一般是通过给别人发送带有恶意脚本代码参数的 URL,当 URL 地址被打开时,特有的恶意代码参数被 HTML 解析、执行。

反射型XSS攻击步骤:

  1. 攻击者构造特殊的URL,其中包含恶意代码。
  2. 用户打开带有恶意代码的URL时,网站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器。
  3. 用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
  4. 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

非持久型XSS的特征:

  • 即时性,不经过服务器存储,直接通过 HTTP 的 GET 和 POST 请求就能完成一次攻击,拿到用户隐私数据。
  • 攻击者需要诱骗点击。
  • 反馈率低,所以较难发现和响应修复。
  • 盗取用户敏感保密信息。

针对非持久型XSS攻击的方法:

  • Web页面渲染的所有内容的数据必须都来自于服务器。
  • 尽量不要从 URL,document.referrerdocument.forms 等这种 DOM API 中获取数据直接渲染。
  • 尽量不要使用 eval, new Function()document.write()document.writeln()window.setInterval()window.setTimeout()innerHTMLdocument.creteElement() 等可执行字符串的方法。
  • 必须对涉及 DOM 渲染的方法传入的字符串参数做 escape 转义。
  • 前端渲染的时候对任何的字段都需要做 escape 转义编码。

escape 转义的目的是将一些构成 HTML 标签的元素转义,比如 <,>,空格 等,转义成 <,>,  等显示转义字符。有很多开源的工具可以协助我们做 escape 转义。

持久型XSS

也被称为存储型XSS漏洞。一般存在于 Form 表单提交等交互功能,如发帖留言,提交文本信息等,黑客利用的 XSS 漏洞,将内容经正常功能提交进入数据库持久保存,当前端页面获得后端从数据库中读出的注入代码时,恰好将其渲染执行。

持久型 XSS 攻击不需要诱骗点击,黑客只需要在提交表单的地方完成注入即可,但是这种 XSS 攻击的成本相对还是很高。

存储型XSS成功的条件:

  • POST 请求提交表单后端没做转义直接入库。
  • 后端从数据库中取出数据没做转义直接输出给前端。
  • 前端拿到后端数据没做转义直接渲染成 DOM。

这些条件是必须同时满足的。

存储型XSS攻击步骤:

  1. 攻击者将恶意代码提交到目标网站的数据库中。
  2. 用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器。
  3. 用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
  4. 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

存储型XSS攻击的特征:

  • 持久性,植入在数据库中
  • 危害面广,甚至可以让用户机器变成 DDoS 攻击的肉鸡。
  • 盗取用户敏感私密信息

针对持久型XSS攻击的方法:

  • 后端在入库前应该选择不相信任何前端数据,将所有的字段统一进行转义处理。
  • 后端在输出给前端数据统一进行转义处理。
  • 前端在渲染页面 DOM 的时候应该选择不相信任何后端数据,任何字段都需要做转义处理。

DOM型XSS

DOM 型 XSS 代码不需要服务器端的解析响应的直接参与,而是通过浏览器端的 DOM 解析。

DOM型XSS攻击步骤:

  • 攻击者构造出特殊的 URL,其中包含恶意代码。
  • 用户打开带有恶意代码的 URL。
  • 用户浏览器接收到响应后解析执行,前端 JavaScript 取出 URL 中的恶意代码并执行。
  • 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

DOM型XSS与反射型XSS

可以看出两种攻击几乎是一模一样的,但是还有一些地方不一样。

两者的关键区别在于:

  • 反射型 XSS 攻击中,服务器在返回 HTML 文档的时候,就已经包含了恶意的脚本。
  • DOM 型 XSS 攻击中,服务器在返回 HTML 文档的时候,是不包含恶意脚本的;恶意脚本是在其执行了非恶意脚本后,被注入到文档里的。

也就是说,反射型 XSS 发生在页面加载时。DOM 型 XSS 发生在页面加载完成后的一段时间内。

CSRF

跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。

利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目。

举个例子,例如,当用户登录网络银行去查看其存款余额,在他没有退出时,就点击了一个 QQ 好友发来的链接,那么该用户银行帐户中的资金就有可能被转移到攻击者指定的帐户中。

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攻击的三条件

  1. 用户已经登录了站点 a,并在本地记录了 cookie。
  2. 在用户没有登出站点 a 的情况下(也就是 cookie 生效的情况下),访问了恶意攻击者提供的引诱危险站点 b (b 站点要求访问站点A)。
  3. 站点 a 没有做任何 CSRF 防御。

你可能会有一个这样的疑惑,那我不让三个条件满足时,是不是可以避免CSRF攻击呢?答案是未然的。

你不能保证你登陆一个网站后,不再去打开另外一个tab页面去访问另外一个网站,特别现在的浏览器都是多tab的。此外,你也不能保证你已关闭浏览器,你的 cookie 立刻过期。

CSRF的特征

  • 攻击一般发起在第三方网站,而不是被攻击的网站。被攻击的网站无法防止攻击发生。
  • 攻击利用受害者在被攻击网站的登录凭证,冒充受害者提交操作;而不是直接窃取数据。
  • 整个过程攻击者并不能获取到受害者的登录凭证,仅仅是“冒用”。
  • 跨站请求可以用各种方式:图片URL、超链接、CORS、Form提交等等。部分请求方式可以直接嵌入在第三方论坛、文章中,难以进行追踪。

防范CSRF

  • 阻止不明外域的访问
    • 同源检测
    • Samesite Cookie
  • 提交时要求附加本域才能获取的信息
    • CSRF Token
    • 双重Cookie验证

SQL注入攻击

SQL 注入攻击,是通过将恶意的 SQL 查询或添加语句插入到应用的输入参数中,再在后台 SQL 服务器上解析执行进行的攻击。可以用它来从数据库获取敏感信息,或者利用数据库的特性执行添加用户,导出文件等一系列恶意操作,甚至有可能获取数据库乃至系统用户最高权限。

SQL注入攻击的步骤

  • 找出SQL漏洞的注入点
  • 判断数据库的类型以及版本
  • 猜解用户名和密码
  • 利用工具查找Web后台管理入口
  • 入侵和破坏

防范SQL攻击的方法

  • 严格限制Web应用的数据库的操作权限,给此用户提供仅仅能够满足其工作的最低权限,从而最大限度的减少注入攻击对数据库的危害。
  • 后端代码检查输入的数据是否符合预期,严格限制变量的类型,例如使用正则表达式进行一些匹配处理。
  • 对进入数据库的特殊字符('"\<>&*; 等)进行转义处理,或编码转换。
  • 所有的查询语句建议使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到 SQL 语句中,即不要直接拼接 SQL 语句。
  • 在应用发布之前建议使用专业的 SQL 注入检测工具进行检测,以及时修补被发现的 SQL 注入漏洞。
  • 避免网站打印出 SQL 错误信息,比如类型错误、字段不匹配等,把代码里的 SQL 语句暴露出来,以防止攻击者利用这些错误信息进行 SQL 注入。
  • 不要过于细化返回的错误信息,如果目的是方便调试,就去使用后端日志,不要在接口上过多的暴露出错信息,毕竟真正的用户不关心太多的技术细节,只要话术合理就行。

参考文献