# 前端安全基础知识

# XSS

跨站脚本攻击(Cross Site Scripting):是一种代码注入攻击。攻击者通过在网站注入恶意脚本,使之在用户浏览器上运行,从而盗取用户信息如cookie等。

攻击者可以通过这种攻击方式进行以下操作:

  • 获取页面数据,如DOM,localStorage,cookie
  • DOS攻击,发送合理请求,占用服务器资源,从而使用户无法访问服务器
  • 破坏页面结构
  • 流量劫持

TIP

XSS(跨站脚本攻击)是指攻击者在返回的HTML中嵌入javascript脚本,为了减轻这些攻击,需要在HTTP头部配上,set-cookie

  • http-only这个属性可以防止XSS,它会禁止javascript脚本来访问cookie
  • secure 这个属性告诉浏览器仅在请求为https的时候发送cookie

# 持久型(存储型 server端)

持久型也就是攻击的代码被服务端写入进数据库中,这种攻击危害性很大,因为如果网站访问量很大的话,就会导致大量正常访问页面的用户都受到攻击。

攻击步骤:

  1. 攻击者将恶意代码提交到⽬标⽹站的数据库中。

# 非持久型(反射型 server端)

非持久型相比于前者危害就小的多了,一般通过修改 URL 参数的方式加入攻击代码,诱导用户访问链接从而进行攻击,服务器端接收数据后处理,然后把带有恶意代码的数据发送到浏览器端,浏览器端解析这段带有 XSS 代码的数据后当做脚本执行,最终完成 XSS 攻击。

# DOM型(浏览器端)

通过修改页面的 DOM 节点形成的 XSSDOMXSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞。

场景:通过 URL 传递参数的功能,如网站搜索、跳转等。 攻击步骤:

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

# 防御XSS

  1. 转义字符

首先,对于用户的输入应该是永远不信任的。最普遍的做法就是转义输入输出的内容,对于引号、尖括号、斜杠进行转义。多的文本可以利用js-xss

  1. CSP

CSP 本质上就是建立白名单,开发者明确告诉浏览器哪些外部资源可以加载和执行。我们只需要配置规则,如何拦截是由浏览器自己实现的。

  • 开启CSP
    • 设置 HTTP Header 中的 Content-Security-Policy
    # 只允许加载本站资源:
    Content-Security-Policy: default-src ‘self’ #-所有内容均来自站点的同一个源(不包括其子域名)
    
    # 只允许加载HTTPS协议图片
    Content-Security-Policy: img-src https://*
    
    # 允许加载任何来源框架
    Content-Security-Policy: child-src 'none'
    
    1
    2
    3
    4
    5
    6
    7
    8
    • 设置 meta 标签的方式 <meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">

上述策略解释

  • 脚本:只信任当前域名
  • <object>标签:不信任任何URL,即不加载任何资源
  • 样式表:只信任cdn.example.orgthird-party.org
  • 框架(frame):必须使用HTTPS协议加载
  • 其他资源:没有限制
  1. 防止脚本读取cookie
  • 可以为Cookie添加HttpOnly属性,防止脚本读取网站的cookie
  • 添加Secure属性要求必须使用https协议才能传输此cookie,可以防止中间人截获修改到传输的cookie
  1. 验证码

# CSRF

CSRF 中文名为跨站请求伪造。原理就是攻击者构造出一个后端请求地址,诱导用户点击或者通过某些途径自动发起请求。如果用户是在登录状态下的话,后端就以为是用户在操作,从而进行相应的逻辑。

  • 防御CSRF

    • Get 请求不对数据进行修改
    • 不让第三方网站访问到用户 Cookie
    • 服务端过滤
      • Origin:域名信息
      • Referer:包含具体URL
      • 开发者可通过自定义请求头伪造
      • 阻止第三方网站请求接口
      • 验证request header中的 Referer/Origin:通过Referer验证请求是否为第三方发送
    • 请求时附带验证信息
      • 添加验证码参数
      • request header中添加一个token字段

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

    • 设置CookieSameSite属性:Cookie 随跨域请求发送的策略
      • Strict:仅允许一方请求携带 Cookie,即浏览器将只发送相同站点请求的 Cookie,当前网页 URL 与请求目标 URL 完全一致才发送
      • Lax:允许部分(导航到目标网址的 Get 请求)第三方请求携带 Cookie
      • None:无论是否跨站都会发送 Cookie

# iframe安全

  1. 嵌入第三方 iframe 会有很多不可控的问题,同时当第三方 iframe 出现问题或是被劫持之后,也会诱发安全性问题
  2. 点击劫持是一种视觉欺骗的攻击手段。攻击者将需要攻击的网站通过 iframe 嵌套的方式嵌入自己的网页中,并将 iframe 设置为透明,在页面中透出一个按钮诱导用户点击。
  3. 禁止自己的 iframe 中的链接外部网站的JS
  • 防御:

    • X-FRAME-OPTIONS

    X-FRAME-OPTIONS 是一个 HTTP 响应头,在现代浏览器有一个很好的支持。这个 HTTP 响应头 就是HTTP 响应头中用来告诉浏览器一个页面是否可以嵌入 <iframe>

    1. DENY:表示页面不允许通过iframe的方式展示
    2. SAMEORIGIN:表示页面可以在相同域名下通过iframe方式展示
    3. ALLOW-FROM:表示页面可以在指定来源的iframe中展示
    • 设置 CSPContent-Security-Policy 请求头
    • 减少对 iframe 的使用

# 中间人攻击

中间人攻击是攻击方同时与服务端和客户端建立起了连接,并让对方认为连接是安全的,但是实际上整个通信过程都被攻击者控制了。攻击者不仅能获得双方的通信信息,还能修改通信信息。没有进行严格的证书校验是中间人攻击着手点。目前大多数加密协议都提供了一些特殊认证方法以阻止中间人攻击。如 SSL (安全套接字层)协议可以验证参与通讯的用户的证书是否有权威、受信任的数字证书认证机构颁发,并且能执行双向身份认证。攻击场景如用户在一个未加密的 WiFi下访问网站。在中间人攻击中,攻击者可以拦截通讯双方的通话并插入新的内容。

当然防御中间人攻击其实并不难,只需要增加一个安全通道来传输信息。HTTPS 就可以用来防御中间人攻击,但是并不是说使用了 HTTPS 就可以高枕无忧了,因为如果你没有完全关闭 HTTP 访问的话,攻击方可以通过某些方式将 HTTPS 降级为 HTTP 从而实现中间人攻击。

img

TIP

  • 过程原理:
    • 本地请求被劫持(如DNS劫持等),所有请求均发送到中间人的服务器
    • 中间人服务器返回中间人自己的证书
    • 客户端创建随机数,通过中间人证书的公钥对随机数加密后传送给中间人,然后凭随机数构造对称加密对传输内容进行加密传输
    • 中间人因为拥有客户端的随机数,可以通过对称加密算法进行内容解密
    • 中间人以客户端的请求内容再向正规网站发起请求
    • 因为中间人与服务器的通信过程是合法的,正规网站通过建立的安全通道返回加密后的数据
    • 中间人凭借与正规网站建立的对称加密算法对内容进行解密
    • 中间人通过与客户端建立的对称加密算法对正规内容返回的数据进行加密传输
    • 客户端通过与中间人建立的对称加密算法对返回结果数据进行解密

由于缺少对证书的验证,所以客户端虽然发起的是 HTTPS 请求,但客户端完全不知道自己的网络已被拦截,传输内容被中间人全部窃取。

  • 常见攻击方式

    • 嗅探:嗅探是一种用来捕获流进和流出的网络数据包的技术,就好像是监听电话一样。比如:抓包工具
    • 数据包注入:在这种,攻击者会将恶意数据包注入到常规数据中的,因为这些恶意数据包是在正常的数据包里面的,用户和系统都很难发现这个内容。
    • 会话劫持:当我们进行一个网站的登录的时候到退出登录这个时候,会产生一个会话,这个会话是攻击者用来攻击的首要目标,因为这个会话,包含了用户大量的数据和私密信息。
    • SSL剥离:HTTPS是通过SSL/TLS进行加密过的,在SSL剥离攻击中,会使SSL/TLS连接断开,让受保护的HTTPS,变成不受 保护的HTTP(这对于网站非常致命)
    • DNS欺骗,攻击者往往通过入侵到DNS服务器,或者篡改用户本地hosts文件,然后去劫持用户发送的请求,然后转发到攻击者想要转发到的服务器
    • ARP欺骗,ARP(address resolution protocol)地址解析协议,攻击者利用APR的漏洞,用当前局域网之间的一台服务器,来冒充客户端想要请求的服务端,向客户端发送自己的MAC地址,客户端无从得到真正的主机的MAC地址,所以,他会把这个地址当作真正 的主机来进行通信,将MAC存入ARP缓存表。
    • 代理服务器
  • 如何防范

    • 使用https
    • 不要在公共wifi上发送敏感数据
    • 使用权威机构的CA证书

# 增强头部安全性

  • Content-Security-Policy响应头,可以设置应用是否可以引用某些来源的内容,进而防止XSS
  • 关闭X-Powered-By响应头,以避免暴露服务器端信息
  • 增加Public Key Pinning响应头,预防中间人伪造证书
  • 设置Strict-Transport-Security响应头,这样浏览器就只能通过HTTPS访问当前资源
  • IE8以上设置X-Download-Options响应头,预防下载内容的安全隐患。
  • 设置Cache-ControlPragma header以关闭浏览器端缓存
  • 设置X-Content-Type-Options响应头,以禁用浏览器内容嗅探
  • 设置X-Frame-Options响应头,以预防clickjacking漏洞。这个响应头可以告诉浏览器是否允许<frame>/<iframe>标签渲染页面
  • 设置X-XSS-Protection响应头,当检测到跨站脚本XSS时,浏览器会停止加载页面。