关于前端安全性那些事
前言
这篇文章鸽了好久了,一直在草稿箱呆着,刚好这周在家休病假,终于有时间更了。
为啥突然想写前端安全性相关的文章了呢?
起因是在逛boss直聘或者前程无忧等提桶软件时,看到很多职位要求都写了精通前端安全性相关问题,我:黑人问号脸.jpg!现在什么都要精通了嘛?
那么前端相关的安全性问题都有哪些呢?
1、XSS攻击
提起前端安全性问题,我第一个想起来的就是XSS( 全称为Cross Site Scripting,为了和CSS分开简写为XSS,也就是跨站脚本注入)。指攻击者在 html 中嵌入script,浏览器遇到 html 中的 script 标签时,会解析并执行其中的js代码,攻击者直接为所欲为。
XSS 的本质是:恶意代码未经过滤,与网站正常的代码混在一起;浏览器无法分辨哪些脚本是可信的,导致恶意脚本被执行
那么问题来了,他怎么在我的html中嵌入代码呢?举个栗子,在三大框架没有出来之前,我们渲染一般通过数据拼接html,然后使用 innerHtml、outerHTML、document.write 的方式,往页面中动态添加渲染元素,假如页面有个查询功能,点击查询按钮后,url会拼接用户输入的 search key,那么攻击者可以通过直接修改url拼接的key为<script>alert('XSS');</script>
,当用户点了这个改造过的url后,查询的key复显,碰巧你没有对用户输入的数据做转义,浏览器遇到 script 标签就会直接执行 alert
。这只是xss攻击最简单的一种方式。
不过现在三大框架已经不需要我们通过上述的方式渲染数据了,再加上模板语法渲染时做了处理,已经很大程度上帮我们避免了这种攻击方式。
除此之外还有很多方式可以注入,美团技术团队分享的 这篇文章 总结的非常好,XSS攻击被分为存储型、反射型和 DOM型三种。
1.1、存储型
存储型就是攻击者将恶意代码提交到目标网站的数据库中,当用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器,用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。
预防这种漏洞,有两种常见做法:
- 纯前端渲染,代码和数据分离,比如vue等框架。
- 对HTML做充分转义,如果拼接html是必须的(比如需要做SEO优化),那么需要对HTML各个插入点进行充分的转义,常用的模板引擎,如 doT.js、ejs、FreeMarker 等。
1.2、反射型
反射型 XSS 的攻击步骤:
攻击者构造出特殊的 URL,其中包含恶意代码。
用户打开带有恶意代码的 URL 时,网站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器。
用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。
由于需要用户主动打开恶意的 URL 才能生效,攻击者往往会结合多种手段诱导用户点击。是不是感觉很熟悉,我们找盗版资源时候,那些网站上那些性感游戏图片??
1.3、DOM型
DOM 型 XSS 攻击,实际上就是网站前端 JavaScript 代码本身不够严谨,把不可信的数据当作代码执行了。 与存储型比较类似,唯一的区别就是DOM型不用通过数据库,也就是开篇时最上面讲的那种,通过serch input 进行注入。
如何预防:
- 如果用 Vue/React 技术栈,并且不使用 v-html/dangerouslySetInnerHTML 功能,就在前端 render 阶段避免 innerHTML、outerHTML 的 XSS 隐患。
- 尽量不使用 .
innerHTML、.outerHTML、document.write()
等方法,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用.textContent、.setAttribute()
等。 location、onclick、onerror、onload、onmouseover
等,<a> 标签的href
属性,JavaScript 的eval()、setTimeout()、setInterval()
等,都能把字符串作为代码运行。尽量避免把不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患。
通用的预防方案: Content Security Policy
- 禁止加载外域代码,防止复杂的攻击逻辑。
- 禁止外域提交,网站被攻击后,用户的数据不会泄露到外域。
- 禁止内联脚本执行(规则较严格,目前发现 GitHub 使用)。
- 禁止未授权的脚本执行(新特性,Google Map 移动版在使用)。
2、 Iframe
2.1、让自己的网站不被其他网站的 iframe 引用
通过判断location,如果不是自己的网站则重定向到其他网站,可以是无法访问的页面,也可以直接给他跳转到百度、谷歌等。
if(top.location != self.location){top.location.href = 'http://xxxxx.com'
}
2.2 、禁用使用iframe内嵌页面操作自己网站
通过h5的新特性 Sandbox
Content-Security-Policy: sandbox;
Content-Security-Policy: sandbox <value>;
可选值如下:
allow-forms
允许嵌入式浏览上下文提交表单。如果未使用此关键字,则不允许此操作。allow-modals
允许嵌入式浏览上下文打开模态窗口。allow-orientation-lock
允许嵌入式浏览上下文禁用锁定屏幕方向的功能。allow-pointer-lock
允许嵌入式浏览上下文使用Pointer Lock API (en-US)。allow-popups
允许弹出窗口(像window.open,target=“_blank”,showModalDialog)。如果未使用此关键字,则该功能将无提示失败。allow-popups-to-escape-sandbox
允许沙盒文档打开新窗口而不强制沙盒标记。例如,这将允许安全地沙箱化第三方广告,而不会对登陆页面施加相同的限制。allow-presentation
允许嵌入器控制 iframe 是否可以启动演示会话。allow-same-origin
允许将内容视为来自其正常来源。如果未使用此关键字,则嵌入的内容将被视为来自唯一来源。allow-scripts
允许嵌入式浏览上下文运行脚本(但不创建弹出窗口)。如果未使用此关键字,则不允许此操作。allow-top-navigation
允许嵌入式浏览上下文将内容导航(加载)到顶级浏览上下文。如果未使用此关键字,则不允许此操作。
2.3、 打开新标签跳转 window.opener
我们常用的打开新标签页的方式通常有两种
<a target='_blank' href='http://www.baidu.com'>
window.open('http://www.baidu.com')
考虑以下场景:
A 页面通过 <a> 或 window.open 方式,打开 B 页面。但是 B 页面存在恶意代码如下:
// 此代码仅针对打开新标签有效
window.opener.location.replace('https://www.baidu.com')
此时,用户正在浏览新标签页,但是原来网站的标签页已经被导航到了百度页面。甚至恶意网站可以伪造一个足以欺骗用户的页面,从而获得用户的敏感信息。即使在跨域状态下 opener 仍可以调用 location.replace 方法。
对于a标签,我们可以采用配置rel属性的方式解决此问题:
// noopener会将 window.opener 置空,从而源标签页不会进行跳转(存在浏览器兼容问题)
<a target="_blank" href="" rel="noopener"></a>
对于window.open
,可采用手动置空的方式解决此问题:
const newTab = window.open();newTab.opener = null;newTab.location = targetUrl;
3、跨站请求伪造(Cross-site request forgery)
wiki百科的解释是这样的:
跨站请求攻击,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并执行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去执行。这利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求是发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。
wiki举的例子:
假如一家银行用以执行转账操作的URL地址如下: https://bank.example.com/withdraw?account=AccoutName&amount=1000&for=PayeeName
那么,一个恶意攻击者可以在另一个网站上放置如下代码:
<img src=“https://bank.example.com/withdraw?account=Alice&amount=1000&for=Badman” />
如果有账户名为Alice的用户访问了恶意站点,而她之前刚访问过银行不久,登录信息尚未过期,那么她就会损失1000资金。
这种恶意的网址可以有很多种形式,藏身于网页中的许多地方。此外,攻击者也不需要控制放置恶意网址的网站。例如他可以将这种地址藏在论坛,博客等任何用户生成内容的网站中。这意味着如果服务端没有合适的防御措施的话,用户即使访问熟悉的可信网站也有受攻击的危险。
防御措施(推荐添加token / HTTP头自定义属性):
- HTTP 协议中使用 Referer 属性来确定请求来源进行过滤
HTTP头中有一个Referer字段,这个字段用以标明请求来源于哪个地址。在处理敏感数据请求时,通常来说,Referer字段应和请求的地址位于同一域名下。以上文银行操作为例,Referer字段地址通常应该是转账按钮所在的网页地址,应该也位于bank.example.com之下。而如果是CSRF攻击传来的请求,Referer字段会是包含恶意网址的地址,不会位于bank.example.com之下,这时候服务器就能识别出恶意的访问。
- 请求地址添加 token ,使黑客无法伪造用户请求
- HTTP 头自定义属性验证(类似上一条)
- Cookie-SameSite属性
Cookie 的SameSite属性用来限制第三方 Cookie,从而减少安全风险。它可以设置三个值。
Strict完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外(只包括三种情况:链接,预加载请求,GET 表单)。
None 关闭SameSite。
还记得浏览器的同源策略吗,也就是跨域访问限制,同源策略确实减少了部分CSRF发生,但并不能完全解决该问题。
4、ClickJacking(点击劫持)
一般会利用透明 iframe 覆盖原网页诱导用户进行某些操作达成目的。
原理非常简单
访问者被恶意页面吸引。怎样吸引的不重要。
页面上有一个看起来很诱人的图片(例如:点我,超好玩!或者美女秘书等你来体验!”)。
恶意页面在该链接上方放置了一个透明的 <iframe>,其 src 来自于 bilibili.com,这使得“点赞”按钮恰好位于该链接上面。这通常是通过 z-index 实现的。
用户尝试点击该链接时,实际上点击的是“点赞”按钮。而你电脑默认已经登陆过了bilibili,你不知不觉就已经给某个视频点了个赞。
推荐的防御方案:
使用X-Frame-Options: DENY
这个HTTP Header来明确的告知浏览器,不要把当前HTTP响应中的内容在HTML Frame中显示出来。
5、HTTPS重定向问题
由于不能改变用户的输入习惯,很多网站在实现全站HTTPS后,选择通过配置强制301的方式让用户的http请求重定向到https,以保障网站的安全性。
比如我们输入“http://www.baidu.com”或“www.baidu.com”最终都会被302重定向到“https://www.baidu.com”。
然而,当我们第一次通过 HTTP 或域名进行访问时,302重定向有可能会被劫持,篡改成一个恶意或钓鱼网站。
对于该问题,推荐看这篇文章,介绍了苏宁遇到该问题的经历。
解决方案就是采用HSTS(HTTP Strict Transport Security)方案。详见文档
6、CDN劫持
出于性能考虑,前端应用通常会把一些静态资源存放到CDN(Content Delivery Networks)上面,例如 某些j 大型 js库或者脚本和 style 文件。这么做可以显著提高前端应用的访问速度。但这也给了别人劫持的可能。如果攻击者劫持了CDN,或者对CDN中的资源进行了污染,攻击者可以肆意篡改我们的前端页面,对用户实施攻击。
劫持的原理我找了几篇文章都没解释清楚,看了知乎上一篇CDN原理简单介绍文章后,梳理下来如下:由于CDN结束本身就是一种DNS(将域名和IP地址相互映射)劫持,只不过CDN是一种良性的劫持,通过负载均衡分发,将从当前地区距离最近的服务器上,把资源返回出去。那么CDN劫持,估计是在DNS劫持的过程中进行了某种操作,对返回的资源做了替换或者修改,从而进行攻击。
解决方案:
在script 和 link 标签上添加 integrity属性,它通过验证获取到的资源的哈希值是否和标签上该属性提供的哈希值一样来判断资源是否被篡改。
<script type="text/javascript" integrity="sha256-mY9nzNMPPf8oL3CJss7THIEoXAC2ToW1tEX0NBhMvuw= sha384-ncIKElSEk2OR3YfjNLRSY35mzt0CUwrpNDVS//iD3dF9vxrWeZ7WPlAPJTqGkSai" crossorigin="anonymous" src="//s.url.cn/xxxx/xxx.js?_offline=1"></script>
使用 SRI 需要两个条件:一是要保证 资源同域 或开启跨域,二是在<script>中 提供签名 以供校验。
关于前端安全性那些事相关推荐
- 威联通nas怎么更换大硬盘_更换NAS后,数据如何安全处理?聊聊NAS数据安全性那些事...
Hello,我又来了. 这是我的第六篇NAS原创了,我也从一个NAS菜鸡,成长为了一个不那么小白的NAS中级用户. 这次来探讨下NAS数据安全性那些事. 也是这一年多来使用的经验总结,虽然主要是针对威 ...
- 群晖nas做文件服务器的安全性,更换NAS后,数据如何安全处理?聊聊NAS数据安全性那些事...
Hello,我又来了. 这是我的第六篇NAS原创了,我也从一个NAS菜鸡,成长为了一个不那么小白的NAS中级用户. 这次来探讨下NAS数据安全性那些事. 也是这一年多来使用的经验总结,虽然主要是针对威 ...
- 2018 浅谈前端面试那些事
1.HTML HTML5新特性,语义化 浏览器的标准模式和怪异模式 xhtml和html的区别 使用data-的好处 meta标签 canvas HTML废弃的标签 IE6 bug,和一些定位写法 c ...
- JeeSite 4.0 说说前端的那些事
2019独角兽企业重金招聘Python工程师标准>>> 引言 一个不得不说的话题,经过近几年的发展,Web前端开发已经不是一个新有的岗位了,前端技术发展非常迅速,技术更新换代也很快, ...
- 合格前端系列第九弹-前端面试那些事
2019独角兽企业重金招聘Python工程师标准>>> 项目相关 自我介绍:职业经历,项目经历 选一个你觉得印象最深的项目讲一讲,然后会从项目里面切入到 web 基础(html/cs ...
- 前端面试那些事【dt/dd、audio、onerror、标签、类、ID选择器、伪类选择器......
前端的那些基本标签
- 你应该知道的前端安全性
1. 概述 本文不是一个大而全的课程,只是我们日常中常见的问题,因为网络安全是一个很大的话题,我们这里只介绍前端工程师应知应会的东西.大概包括XSS,CSRF,点击劫持,SQL注入,OS注入,请求劫持 ...
- 最新Web前端经典面试试题(Marksheng全网最不讲武德的版本)
第一篇 近期总结一一些面试题 都是企业的面试题笔记题 感觉薪资10k下的都会出笔试题 特别高的薪资都是直接技术面试或者是 现场编程 总结很多人的面试题,后期会对于单个知识点再说笔记详细讲解. 部分都是 ...
- 霖呆呆的中大厂面试记录及2年前端薪资对比(附赠学习方法)
前言 呆呆最近挺感慨的,因为从四月中旬开始准备面试,到面各个中小公司,大厂,距离今天已经将近2个月了.期间经历过不少事情,也带来了些许的成长. 那么这篇文章主要是说明一下这段时间自己在面不同规模的公司 ...
最新文章
- 对Thrift的一点点理解
- GitHub网站使用的基础入门
- JavaScript实现唯一路径问题的动态编程方法的算法(附完整源码)
- EA强大的画图工具---设计数据库表格
- GitHub上线Trending功能,帮你轻松找到有潜力的开源项目
- 咸宁省2021年模拟高考成绩查询怎么查,2021咸宁市地区高考成绩排名查询,咸宁市高考各高中成绩喜报榜单...
- csnd ftp服务器端java_数据包取证总结 - osc_r6zeu2c7的个人空间 - OSCHINA - 中文开源技术交流社区...
- Python网络编程基础【底层网络】
- mysql public权限_MySQL · 引擎特性 · Binlog encryption 浅析
- Expression Blend实例中文教程(11) - 视觉管理器快速入门Visual State Manager(VSM)
- 智慧小区云平台解决方案
- Embarcadero® Delphi 10.3源码安装fastreport6
- 使用AD14创建异形PCB板
- 记录使用Kettle导入excel数据心得
- 新书《完美统计图:Word/PPT/Excel数据可视化宝典》,包邮送
- IDEA设置成白色背景
- ThinkPHP 导入的几种方法
- 2019互联网行业面试资料合集
- Google File System中文翻译
- 媒体谈北京豪车遍地报道:传递羡富价值观刺激社会
热门文章
- 遥感图像MEL文件解读
- C++实验6 改造实验5中的Player类、自行设计字符串类
- 拉卡拉叠加式便民服务有效满足商户各类需求
- JS 跑马灯效果实现(很好用)
- ios开发 方形到圆的动画_iOS利用UIBezierPath + CAAnimation实现路径动画效果
- 面试官:您能说说序列化和反序列化吗?是怎么实现的?什么场景下需要它?
- 1. 初学prometheus监控
- Ehcache配置详解
- TCP端口号范围及分类
- 使用Vue-cli从零开始搭建Vue全家桶(仿b站客户端)项目(3.主页和视频播放页面的实现)