Skip to content
On this page

常见的攻击手段 ​

XSS ​

攻击者将可以执行的代码注入到网页中。

  • 持久型

  • 非持久型

注入点:

  • HTML 节点内容

  • HTML 属性(img onerror属性)

  • JavaScrit 代码

  • 富文本

持久型就是将攻击代码写入到了数据库中,这种危害性很大,会导致大量正常访问网站的用户受到攻击。

举个例子,对于评论功能来说,就得防范持久型 XSS 攻击,因为可以在评论中输入以下内容

comment.png

这种情况如果前后端没有做好防御的话,这段评论就会被存在数据库中,这样每个打开页面的用户都会被攻击到。

非持久型相比危害小的多,一般通过修改 URL 参数的方式加入攻击代码,诱导用户访问链接从而攻击。举个例子,如果页面需要从 URL 中获取某些参数作为内容的话,不经过过滤会导致攻击代码被执行

html
<!-- http://www.test.com?test=<script>alert(1)</script> -->
<div>{{test}}</div>

但是对于这种攻击方式,如果用户使用 Chrome 这类浏览器的话,浏览器就能自动帮助用户防御攻击。但是我们不能因此就不防御,因为不用确保用户使用了哪类浏览器。

对于 XSS 攻击来说,通常有两种方式用来防御:

转义字符 ​

用户的输入是不可信任的。最普遍的做法就是转义输入输出的内容,对于引号、尖括号、斜杆进行转义处理。

js
{
  // 将str中的html符号转义,将转义“',&,<,",>”五个字符
  escapeHtml (str) {
    return str
      ? str.replace(
        reg || /[&<">'](?:(amp|lt|quot|gt|#39|nbsp|#\d+);)?/g,
        function (a, b) {
          if (b) {
            return a
          } else {
            return {
              '<': '&lt;',
              '&': '&amp;',
              '"': '&quot;',
              '>': '&gt;',
              "'": '&#39;'
            }[a]
          }
        }
      )
      : ''
  },
  decodehtml (str) {
    return str
      ? str.replace(/&((g|l|quo)t|amp|#39|nbsp);/g, function (m) {
        return {
          '&lt;': '<',
          '&amp;': '&',
          '&quot;': '"',
          '&gt;': '>',
          '&#39;': "'",
          '&nbsp;': ' '
        }[m]
      })
      : ''
  }
}

通过转义可以将攻击代码 <script>alert(1)</script> 变成

js
// -> &lt;script&gt;alert(1)&lt;&#x2F;script&gt;
escapeHtml('<script>alert(1)</script>')

但是对于富文本来说,显然不能通过上面的方法来转义所有字符,因为这样会把需要的格式也会过滤掉。对于这种可以使用 js-xss 插件来实现,设置白名单过滤

js
const xss = require('xss')
let html = xss('<h1 id="title">XSS Demo</h1><script>alert("xss");</script>')
// -> <h1>XSS Demo</h1>&lt;script&gt;alert("xss");&lt;/script&gt;
console.log(html)

CSP ​

CSP 本质就是建立白名单。开发者明确浏览器哪些外部的资源可以加载和执行,只需要配置相关规则,如何拦截由浏览器自己实现;可以通过这种方式来尽量减少 XSS 攻击。

通过两种方式开启 CSP:

  • 设置 HTTP Header 中的 Content-Security-Policy
bash
# 只允许加载本站资源
Content-Security-Policy: default-src ‘self’

# 只允许加载 HTTPS 协议图片
Content-Security-Policy: img-src https://*

# 允许加载任何来源框架
Content-Security-Policy: child-src 'none'

更多设置可以查看文档

  • 设置 meta 标签的方式 <meta http-equiv="Content-Security-Policy">

这种方式,只要开发者配置正确的规则,那么即使网站存在漏洞,攻击者页不能执行它的攻击代码,并且 CSP 的兼容性也不错。

TIP

幸运的是目前前端主流的框架已解决 XSS 攻击,如:Vue、React、Angular

CSRF ​

CSRF - 跨站请求伪造。

在其它的网站对目标网站发送请求,而这些请求是在用户不知情的情况下完成的。它是发生在匿名的情况下,第三方网站,带上Cookies,向你的网站发送请求,不访问你的前端。

攻击原理

  • 用户登录 A 网站

  • A 网站确认身份

  • B 网站向 A 网站发送请求(带 A 网站的身份)

举个例子,假设网站由一个通过 GET 请求提交用户评论的接口,那么攻击者就可以在钓鱼网站中加入一个图片,图片的地址就是评论接口

js
<img src="http://www.test.com/xxx?comment='attack'"/>

那么你是否会想到使用 POST 方式提交请求是不是就没有这个问题了呢?其实并不是,使用这种方式也不是百分百安全的,攻击者同样可以诱导用户进入某个页面,在页面中通过表单提交 POST 请求。

防御 ​

防御 CSRF 可以遵循以下规则:

  • GET 请求不对数据进行修改

  • 不让第三方网站访问到用户 Cookie

  • 阻止第三方网站请求接口

  • 请求时附带验证信息,如 TOKEN

SameSite ​

可以对 Cookie 设置 SameSite 属性。该属性表示 Cookie 不随着跨域请求发送,可以很大程度减少 CSRF 的攻击,但是该属性目前并不是所有浏览器都兼容。

Referer ​

对于需要防范 CSRF 的请求,我们可以通过验证 Referer 来判断该请求是否为第三方网站发起的。

Token ​

服务器下发一个随机 Token,每次发起请求时将 Token 携带上,服务器验证 Token 是否有效。

点击劫持 ​

点击劫持是一种视觉欺骗的攻击手段。

攻击者将需要攻击的网站通过 iframe 嵌套的方式嵌入自己的网页中,并将 iframe 设置为透明,在页面中透出一个按钮诱导用户点击。

  • X-FRAME-OPTIONS

X-FRAME-OPTIONS 是一个 HTTP 响应头。这个 HTTP 响应头 就是为了防御用 iframe 嵌套的点击劫持攻击。

bash
header('X-Frame-Options:DENY')

该响应头有三个值可选,分别是

  1. DENY:表示页面不允许通过 iframe 的方式展示

  2. SAMEORIGIN:表示页面可以在相同域名下通过 iframe 的方式展示

  3. ALLOW-FROM:表示页面可以在指定来源的 iframe 中展示

  • JS 防御

JavaScript 禁止内嵌

JS
<script>
    if (top.location != window.location){
        top.location = window.location 
    }
</script>

上传问题 ​

  • 上传文件

  • 再次访问上传的文件

  • 上传的文件被当成程序解析

上传问题防御 ​

  • 限制上传的后缀

  • 检查文件类型

  • 检查文件内容

  • 程序输出

  • 权限控制——可写可执行互斥

中间人攻击 ​

中间人攻击是攻击方同时与服务端和客户端建立起了连接,并让对方认为连接是安全的,但是实际上整个通信过程都被攻击者控制了。攻击者不仅能获得双方的通信信息,还能修改通信信息。

通常来说不建议使用公共的 Wi-Fi,因为很可能就会发生中间人攻击的情况。如果你在通信的过程中涉及到了某些敏感信息,就完全暴露给攻击方了。

防御 ​

  • 增加一个安全通道来传输信息

HTTPS 就可以用来防御中间人攻击,但是并不是说使用了 HTTPS 就可以高枕无忧了,因为如果你没有完全关闭 HTTP 访问的话,攻击方可以通过某些方式将 HTTPS 降级为 HTTP 从而实现中间人攻击。