前端安全 | 青训营

176 阅读6分钟

一、常见前端安全问题

按常见程度排序
  1. XSS(跨站脚本攻击)
  2. CSRF(跨站请求伪装)
  3. ClickJacking(点击劫持)
  4. HSTS(HTTP严格传输安全)
  5. CND劫持
  6. iframe
  7. opener

二、XSS (跨站脚本攻击)

XSS全称 ( CRoss Site Scripting ) 跨站脚本攻击,是前端最常见的安全问题
  • XSS 是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其他用户使用的页面中
  • 攻击者通过注入非法的 html标签 或者 JavaScrpipt代码, 从而当用户浏览该网页时,控制用户浏览器

这里推荐一篇文章,是美团技术团队出的 --> 如何防止XSS攻击

Ⅰ - DOM类型 xss

利用DOM本身存在的缺陷进行攻击

举个🌰:

 //正常写代码
 <img src='绑定正确的路径' />
 //xss攻击  -->将其绑定的src弄成错误的,这样就会走到 innerror中的代码
 <img src='/错误的代码' onerror='恶意代码块'>

① 攻击步骤

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

Ⅱ - 反射型xss (非持久性)

  • 反射型xss也被称为非持久性XSS, 是现在最容易出现的一种XSS漏洞
  • XSS代码出现在URL中,通过引诱用户点击一个链接到目标网站的恶意链接来实施攻击(是不是很熟悉)

举个栗子

 //其中 `xxx` 代表恶意代码
 https://gitee.com/hongjilin?data=xxx
  • xxx是恶意代码,传到服务器的参数data被服务器接收之后
  • 响应的页面包含data这个变量的,会将恶意代码注入到页面上,进行攻击

① 攻击步骤

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

② 特点

  • 反射型XSS漏洞常见于通过URL传递参数的功能,如网站搜索、跳转等
  • 由于需要用户主动打开恶意URL才能生效(像是你发了一段恶意链接给人,通常都不会自动运行的,只有你手动点击触发),攻击者往往会结合多种手段诱导用户点击(只要你触发了就会跳转或者运行恶意代码)
  • POST的内容也可以触发反射型XSS,只不过其触发条件比较苛刻(需要构造表单提交页面,并引导用户点击),所以非常少见

Ⅲ - 存储型xss (持久性)

① 特点

  • 存储型XSS又被称为 持久性XSS , 它是最为危险的一种跨站脚本
  • 相比 反射型XSSDOM型 : 它具有更高的隐蔽性,所以危害更大,它不需要用户手动触发
  • 当攻击者提交一段XSS代码后被服务端接收并存储,当所有浏览者访问某个页面时都会被XSS
  • 其中最典型的栗子就是 留言板

② 攻击步骤

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

这种攻击常见于带有用户保存数据的网站功能: 如 论坛发帖商品评论用户私信

Ⅳ - 反射型与存储型XSS的区别

  • 反射型XSS(非持久性)的恶意代码存储在URL中
  • 存储型XSS(持久性)的恶意代码存储在数据库中

Ⅴ - DOM型跟其他两种XSS的区别

DOM型XSS攻击中

  • 取出和执行恶意代码由浏览器端完成,属于前端JavaScript本身的安全漏洞;
  • 其他两种都属于服务端的安全漏洞

Ⅵ - 解决方案

① httpOnly

在cookie中设置HttpOnly属性, 使得JS脚本无法读取到cookie信息

② 输入过滤

对用户的输入进行过滤,通过将 <>''""等字符进行转义,移除用户输入的Style节点、Script节点、iframe节点

 const filterXSS(str){
 let s= '';
 if(str.length == 0) return "";
 s = str.replace(/&/g,"&amp;");
 s = s.replace(/</g,"&lt;");
 s = s.replace(/>/g,"&gt;");
 s = s.replace(/ /g,"&nbsp;");
 s = s.replace(/'/g,"&#39;");
 s = s.replace(/"/g,"&quot;");
 return s; 
 }

③ 转义HTML

  • 根据输出数据所在的上下文来进行相应的编码
  • 数据放置于HTML元素中,需进行 HTML编码
  • 放置于 URL 中,需要进行 URL编码
  • 还有 JavaScript编码CSS编码HTML编码JSON编码

④ 预防 存储型、反射型XSS攻击

此方法主要预防 存储型和反射型XSS攻击

纯前端渲染过程

  • 浏览器先加载一个静态HTML,此HTML中不包含任何跟业务相关的数据
  • 然后浏览器执行HTML中的JavaScript
  • JavaScript 通过 Ajax 加载业务数据,调用 DOM API 更新到页面上

在纯前端渲染中,我们会明确告诉浏览器:下面要设置的内容是文本(.innerText),还是属性(.setAttribute),还是样式(.style)等等。浏览器不会被轻易的被欺骗,执行预期外的代码了

  • 但纯前端渲染就需要注意避免DOM型的XSS漏洞
  • 在很多内部、管理系统中,采用纯前端渲染是非常适合的,但对于性能要求高;
  • 或有SEO需求的页面,我们仍要面对拼接HTML的问题

⑤ 预防DOM型XSS攻击

DOM型XSS攻击,实际上就是网站前端JavaScript本身不够严谨,把不可信的数据当代码执行了

  • 在在使用 .innerHTML.outerHTMLdocument.write() 时要特别小心,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用 .textContent.setAttribute() 等。
  • 如果用 Vue/React 技术栈,并且不使用 v-html/dangerouslySetInnerHTML 功能,就在前端 render 阶段避免 innerHTMLouterHTML 的 XSS 隐患。
  • DOM 中的内联事件监听器,如 locationonclickonerroronloadonmouseover 等,<a> 标签的 href 属性,JavaScript 的 eval()setTimeout()setInterval() 等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,请务必避免。