一、常见前端安全问题
按常见程度排序
- XSS(跨站脚本攻击)
- CSRF(跨站请求伪装)
- ClickJacking(点击劫持)
- HSTS(HTTP严格传输安全)
- CND劫持
- iframe
- 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, 它是最为危险的一种跨站脚本- 相比 反射型XSS 和 DOM型 : 它具有更高的隐蔽性,所以危害更大,它不需要用户手动触发
- 当攻击者提交一段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,"&"); s = s.replace(/</g,"<"); s = s.replace(/>/g,">"); s = s.replace(/ /g," "); s = s.replace(/'/g,"'"); s = s.replace(/"/g,"""); 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、.outerHTML、document.write()时要特别小心,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用.textContent、.setAttribute()等。- 如果用 Vue/React 技术栈,并且不使用
v-html/dangerouslySetInnerHTML功能,就在前端 render 阶段避免innerHTML、outerHTML的 XSS 隐患。- DOM 中的内联事件监听器,如
location、onclick、onerror、onload、onmouseover等,<a>标签的href属性,JavaScript 的eval()、setTimeout()、setInterval()等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,请务必避免。