上呼吸道医生开药:头孢地尼,清热散结胶囊,喉咽清颗粒。记一下,事实证明自己买的药都是安慰剂。

前端安全分类

经典的前端攻击主要是两种:XSSCSRF

XSS

XSS(Cross-Site Scripting),跨站脚本攻击是一种代码注入攻击。攻击者在目标网站上注入恶意 JS 代码,当被攻击者访问被注入的网站时,这些恶意代码就会执行,这些代码可能是获取 Cookie,session,tokens 或者其他用户数据,甚至可以发起 XSS 蠕虫攻击。

根据 XSS 的来源,XSS 攻击可以分为三类:

  1. 反射性(非持久型)
  2. 存储型(持久型)
  3. DOM 型

反射型 XSS

反射型 XSS 漏洞常见于通过URL传递参数的功能,如网站搜索,跳转等。反射型是最常用,也是使用得最广的一种攻击方式,由于需要用户主动打开恶意的URL才能生效,攻击者往往会通过许多手段诱导用户点击。

当用户点击一个恶意链接时,注入脚本进入被网站的服务器,如果该服务器存在 XSS 漏洞,脚本未被过滤被返回给浏览器,该脚本就会执行。

反射型 XSS 的攻击步骤

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

反射型 XSS 实例:一个例子 感谢这篇文章的作者。

反射型 XSS 的防范

对字符串进行编码。

对 url 参数要进行转义后再返回页面。

存储型 XSS

存储型 XSS 常见于带有用户保存数据的网站,如论坛发帖,评论,用户私信等。
恶意脚本被永久的存储在目标服务器上。每当浏览器请求相关数据时,恶意脚本就会被返回并执行,影响范围更大。

存储型 XSS 攻击的原因仍是没有做好数据过滤。
前端提交数据至服务端时,没有做好过滤;服务端在接受到数据时,在存储之前,没有做过滤;前端从服务端请求到数据,没有过滤输出。

存储型 XSS 的攻击步骤

  1. 攻击者将恶意代码提交到目标网站的数据库中。
  2. 当用户打开网站时,比如一个文章的评论区,网站服务器将恶意代码从数据库中取出来,拼接 HTML 返回给浏览器
  3. 浏览器收到响应后解释执行,其中的恶意代码也会执行
  4. 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户行为,调用网站接口执行某些操作。

每有一个用户访问这个文章的评论区,恶意代码都会执行一遍。

反射型 XSS 的防范

对字符串进行编码。

  1. 前端数据传递给服务器之前,先转义/过滤(防范不了抓包修改数据的情况)
  2. 服务器接收到数据,在存储到数据库之前,进行转义/过滤
  3. 前端接收到服务器传递过来的数据,在展示到页面前,先进行转义/过滤

DOM 型 XSS 攻击

DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞。

DOM 型 XSS 攻击,实际上就是前端 JavaScript 代码不够严谨,把不可信的内容插入到了页面。在使用 .innerHTML、.outerHTML、.appendChild、document.write()等 API 时要特别小心,不要把不可信的数据作为 HTML 插到页面上,尽量使用 .innerText、.textContent、.setAttribute() 等。

DOM 型 XSS 的攻击步骤:

  1. 击者构造出特殊数据,其中包含恶意代码。
  2. 用户浏览器执行了恶意代码。
  3. 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

DOM 型 XSS 实例:一个例子 再次感谢

DOM 型 XSS 的防范

不要将用户输入的数据直接使用,加入 DOM

  1. 对于 url 链接(例如图片的 src 属性),那么直接使用 encodeURIComponent 来转义。
  2. 非 url,我们可以这样进行编码:
    1
    2
    3
    4
    5
    6
    7
    function encodeHtml(str) {
    return str
    .replace(/"/g, '"')
    .replace(/'/g, ''')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    }

CSRF 攻击

CSRF(cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入恶意网站,在恶意网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

典型的 CSRF 攻击步骤:

  1. 受害者登录 A 站点,并保留了登录凭证(Cookie)
  2. 攻击者诱导受害者访问了站点 B。
  3. 站点 B 向站点 A 的服务器发送了一个请求,浏览器会默认携带站点 A 的 Cookie 信息。
  4. 站点 A 服务器接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是无辜的受害者发送的请求。
  5. 站点 A 服务器以受害者的名义执行了站点 B 的请求。
  6. 攻击完成,攻击者在受害者不知情的情况下,冒充受害者完成了攻击。
2019-5-15-上呼吸道感染之前端安全-2019-5-15-1
2019-5-15-上呼吸道感染之前端安全-2019-5-15-1

CSRF 的特点

  1. 攻击通常在第三方网站发起,如图上的站点 B,站点 A 无法防止攻击发生。
  2. 攻击利用受害者在被攻击网站的登录凭证,冒充受害者提交操作;并不会去获取 cookie 信息(cookie 有同源策略)
  3. 跨站请求可以用各种方式:图片 URL、超链接、CORS、Form 提交等等(来源不明的链接,不要点击)

CSRF 攻击的防范

  1. 添加验证码
    验证码能够防御 CSRF 攻击,但是我们不可能每一次交互都需要验证码,否则用户的体验会非常差,但是我们可以在转账,交易等操作时,增加验证码,确保我们的账户安全。
  2. 使用 Token(主流)
    CSRF 攻击之所以能够成功,是因为服务器误把攻击者发送的请求当成了用户自己的请求。那么我们可以要求所有的用户请求都携带一个 CSRF 攻击者无法获取到的 Token。服务器通过校验请求是否携带正确的 Token,来把正常的请求和攻击的请求区分开。跟验证码类似,只是用户无感知。

    • 服务端给用户生成一个 token,加密后传递给用户
    • 用户在提交请求时,需要携带这个 token
    • 服务端验证 token 是否正确
  3. 判断请求的来源:检测 Referer(并不安全,Referer 可以被更改)
    Referer 可以作为一种辅助手段,来判断请求的来源是否是安全的,但是鉴于 Referer 本身是可以被修改的,因为不能仅依赖于 Referer

  4. Samesite Cookie 属性

为了从源头上解决这个问题,Google 起草了一份草案来改进 HTTP 协议,为 Set-Cookie 响应头新增 Samesite 属性,它用来标明这个 Cookie 是个“同站 Cookie”,同站 Cookie 只能作为第一方 Cookie,不能作为第三方 Cookie,Samesite 有两个属性值,分别是 Strict 和 Lax。

部署简单,并能有效防御 CSRF 攻击,但是存在兼容性问题。

  1. Samesite=Strict
    Samesite=Strict 被称为是严格模式,表明这个 Cookie 在任何情况都不可能作为第三方的 Cookie,有能力阻止所有 CSRF 攻击。此时,我们在 B 站点下发起对 A 站点的任何请求,A 站点的 Cookie 都不会包含在 cookie 请求头中。
  2. Samesite=Lax
    Samesite=Lax 被称为是宽松模式,与 Strict 相比,放宽了限制,允许发送安全 HTTP 方法带上 Cookie,如 Get / OPTIONSHEAD 请求.
    但是不安全 HTTP 方法,如: POST, PUT, DELETE 请求时,不能作为第三方链接的 Cookie

为了更好的防御 CSRF 攻击,我们可以组合使用以上防御手段。

最后

网站安全监测:Mozilla HTTP Observatory