同源策略(Same-origin policy)

URL 的协议、域名和端口都相同

  • DOM 层面:同源策略限制来自不同源的 JS 脚本对于 DOM 对象的读写操作
  • 数据层面:对于 Cookie、IndexDB、LocalStorage 等数据的访问限制
  • 网络层面:限制通过 XMLHttpRequest 等方式将站点的数据发送给不同源的站点

    跨域问题

    CORS(Cross-origin resource sharing,跨域资源共享)

    1. Access-Control-Allow-Origin: http://api.bob.com

    服务器代理

    服务器不存在跨域问题,由服务器请求所有域的资源再返回给客户端

跨站脚本攻击(Cross Site Scripting,XSS)

页面被注入恶意代码

  • 在 HTML 中内嵌的文本中,恶意内容以 script 标签形成注入。
  • 在内联的 JavaScript 中,拼接的数据突破了原本的限制(字符串,变量,方法名等)。
  • 在标签属性中,恶意内容包含引号,从而突破属性值的限制,注入其他属性或者标签。
  • 在标签的 href、src 等属性中,包含 javascript: 等可执行代码。
  • 在 onload、onerror、onclick 等事件中,注入不受控制代码。

    存储型 XSS

    The-process-of-stored-XSS-Attack.png
    这种攻击常见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等。

    放射型 XSS

    reflected_xss.jpg
    反射型 XSS 跟存储型 XSS 的区别是:存储型 XSS 的恶意代码存在数据库里,反射型 XSS 的恶意代码存在 URL 里。
    反射型 XSS 漏洞常见于通过 URL 传递参数的功能,如网站搜索、跳转等。

    DOM 型 XSS

    50f35a32a581f1d6f9a408d4ec9d135d.png
    DOM 型 XSS 跟前两种 XSS 的区别:DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞。

    预防

  1. 服务器对输入脚本进行过滤或转码
  2. 充分利用 CSP(Content Security Policy)
    • 禁止加载外域代码,防止复杂的攻击逻辑。
    • 禁止外域提交,网站被攻击后,用户的数据不会泄露到外域。
    • 禁止内联脚本执行(规则较严格,目前发现 GitHub 使用)。
    • 禁止未授权的脚本执行(新特性,Google Map 移动版在使用)。
    • 合理使用上报可以及时发现 XSS,利于尽快修复问题。
  3. 使用 HttpOnly 属性
    1. set-cookie: NID=189=M8q2FtWbsR8RlcldPVt7qkrqR38LmFY9jUxkKo3-4Bi6Qu_ocNOat7nkYZUTzolHjFnwBw0izgsATSI7TZyiiiaV94qGh-BzEYsNVa7TZmjAYTxYTOM9L_-0CN9ipL6cXi8l6-z41asXtm2uEwcOC5oh9djkffOMhWqQrlnCtOI; expires=Sat, 18-Apr-2020 06:52:22 GMT; path=/; domain=.google.com; HttpOnly

    JS 脚本无法读取设置了 HttpOnly 的 Cookie 数据

跨站请求伪造(Cross-site request forgery,CSRF)

3d7f097b1d6a8f93a960a12892f1556b.png

攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

2009040916453171.jpg

CSRF 的特点

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

    防护策略

    利用 Cookie 的 SameSite 属性

    1. set-cookie: 1P_JAR=2019-10-20-06; expires=Tue, 19-Nov-2019 06:36:21 GMT; path=/; domain=.google.com; SameSite=none
  • Strict:浏览器会完全禁止第三方 Cookie

  • Lax:在跨站点的情况下,从第三方站点的链接打开和从第三方站点提交 Get 方式的表单这两种方式都会携带 Cookie
  • None:在任何情况下都会发送 Cookie 数据

    验证请求的来源站点

  • Referer:HTTP 请求头中的一个字段,记录了该 HTTP 请求的来源地址

  • Origin:通过 XMLHttpRequest、Fecth 发起跨站请求或者通过 Post 方法发送请求时,都会带上 Origin 属性,只包含了域名信息,并没有包含具体的 URL 路径

    CSRF Token

  1. 在浏览器向服务器发起请求时,服务器生成一个 CSRF Token,将 CSRF Token 输出到页面中
  2. 页面提交的请求携带这个
  3. 服务器验证 Token 是否正确

    参考资料

  4. 前端安全系列(一):如何防止XSS攻击?

  5. 33 | 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?
  6. 前端安全系列(二):如何防止CSRF攻击?
  7. 34 | CSRF攻击:陌生链接不要随便点