前端隐秘角落 - web安全的演变历程
前言:隐秘的角落番外篇
这是一个平行时空,在这里,朱朝阳还是有写日记的习惯,不是在日记本,却是在qq中记录。这一天,在他身上发生了一个奇怪的事情:当他像往常一样登录自己的qq空间,却发现最新一条的说说是一个六峰山旅游的广告,但这并不是他写的……这条说说是怎么来的?针对这个问题,他去请教了自己的程序员舅舅张东升。
张东升摸了摸自己的秃头:”你这是被csrf攻击了!“
“接下来我带你来走进web发展史,了解下web安全一路走来的演变历程...”
这篇文章主要围绕web页面安全展开分析:从cookie的源起,到同源策略的出现,再到跨域的兴起,从而引申出csrf攻击。
浏览器的诞生:
追溯到1989年3月12日,万维网 (WWW, World Wide Web) 诞生的日子,蒂姆·伯纳斯-李爵士设计发明了第一个浏览器,架设了第一个 web 服务器 http://info.cern.ch。(详细的介绍在之前文章【http请回答】中有系统的介绍过,可翻阅)而浏览器web的设计之初是知识的共享,所以开放是基本理念。
Cookie
源起:
早期互联网只是用于简单的浏览文档信息、查看门户网站等等,并没有交互这个说法。随着互联网快速发展,交互式web开始兴起,如用户登录,购买商品,各种论坛等。怎么记录用户的操作行为呢?
于是出现了 隐藏域
, 把用户上一次操作记录放在form表单的input中,通过表单提交记录用户操作行为。但是每次都得创建隐藏域而且得赋值太麻烦,且易出错。
// 隐藏域写法
<input type="hidden" name="field_name" value="value">
Cookie最早是网景公司的前雇员Lou Montulli(卢-蒙特利)在1993年3月的发明,并于1994年将“cookies”的概念应用于网络通信。Cookie的出现是为了优化交互式web,同时也规避了隐藏域操作复杂的问题。
定义:
Cookie是由服务器发给客户端的特殊信息,而这些信息以文本文件的方式存放在客户端,然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息,用于服务器记录客户端的状态。
安全性:
cookie在行使自身使命的同时,也存在了安全隐患。
设想一下,你登录了银行系统,并把登录信息、账号密码存在了cookie中,cookie信息共享,大家的账号和密码也共享了,奋斗了一辈子的财富,被别人轻易的转走,将是多么可怕的事情。所以,为了维护互联网的隐私和数据安全,必须制定一定规则。
浏览器安全的基石是"同源政策"(same-origin policy)
--- 阮一峰
同源策略
定义:
源是主机,协议,端口名的一个三元组。1995年,同源政策(SOP)由 Netscape 公司引入浏览器,规定了不同域之间访问的策略 协议://域名:端口
。同domain(或ip),同端口,同协议视为同一个域,一个域内的脚本只能读写本域内的资源,对于其它域的资源,它没有禁止脚本的执行,而是禁止读取HTTP回复,这种安全限制称为同源策略。
为什么同源限定是三元组?不是二元组?也不是四元组?
如果将这个地址组成,比喻为一次快递小哥为合租的你服务的一次行为,那么 协议
则来区分是送快递还是点外卖行为;域名
则是你的地址,端口
则是你的房间号, 请求资源地址
则是你需要点的外卖内容,快递小哥根据你的行为和你的地址,房间号来完成这次任务,就算你临时替换了外卖内容,也不影响他完成这次输送任务。
限制范围
无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB。
无法接触非同源网页的 DOM。
无法向非同源地址发送 AJAX 请求(可以发送,但浏览器会拒绝接受响应)。
同源策略提升了Web前端的安全性,但阻碍了Web拓展的灵活性。若把html、js、css、flash,image等静态文件全部布置在一台服务器上,会加大这台服务器的压力,甚至威胁到web服务的可用性。因此,在遵循同源策略的基础上,在安全性和可用性之间选择了一个平衡点。
tips:以下标签是允许跨域加载资源:
* <img src=XXX>
* <link href=XXX>
* <script src=XXX>
* <iframe>
在日益发展的互联网时代,在前端资源和后端数据请求趋向专业化分离的背景下,需要程序员基于同源策略下,打破常规,实现数据请求加载。这就要进行 跨域
。
跨域
什么是跨域?
由于同源策略的限制,当一个请求 url 的协议、域名、端口
三者之间任意一个与当前页面 url 不同即为跨域,这是浏览器安全限制下的产物。
问:跨域只存在于浏览器吗?
答: 是的,这是浏览器的同源策略下的产物,上文中提到,同源策略没有禁止脚本的执行,而是禁止读取HTTP回复。跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。所以,服务端不存在,服务器间的调用,一般是为了获取接口数据的,单一功能。app也相对比较自由,可自行设置白名单等限定条件。
跨域方式
1、
通过jsonp跨域
(get请求)2、
document.domain + iframe 跨域
(主域相同,子域不同, 设置document.domain为基础主域)3、
location.hash + iframe 跨域
(不同域之间利用iframe的location.hash传值)4、
window.name + iframe 跨域
(name值[2MB]在不同的页面加载后依旧存在)5、
postMessage 跨域
(跨文档通信)6、
跨域资源共享(CORS)
(W3C 标准,跨源ajax请求的根本解决方式)7、
nodejs中间件代理跨域
(服务器向服务器请求)8、
nginx代理跨域
(类似于node中间键,使用中转nginx服务器来转发请求)9、
WebSocket协议跨域
(利用双向通信协议)
这里主要分析下,jsonp 和 cors 跨域方式
JSONP 跨域
JSONP是JSON with Padding的略称。它是一个非官方的协议.
上文讲到,<script>
标签是没有被同源策略限制的,jsonp
利用这个漏洞,向网页中动态插入script
标签,向服务端发送请求,并允许用户传递一个callback
参数给服务端,然后服务端返回数据时会将这个callback
参数作为函数名来包裹住JSON数据,这样前端可以随意定制自己的函数来自动处理返回数据了。
// index.html
function jsonp({ url, params, callback }) {return new Promise((resolve, reject) => {let script = document.createElement('script')window[callback] = function(data) {resolve(data)document.body.removeChild(script)}params = { ...params, callback } // wd=b&callback=showlet arrs = []for (let key in params) {arrs.push(`${key}=${params[key]}`)}script.src = `${url}?${arrs.join('&')}`document.body.appendChild(script)})
}
// 调用
jsonp({url: 'http://localhost:3000/say',params: { wd: 'HowAreYou' },callback: 'show'
}).then(data => {console.log(data)
})// server.js
let express = require('express')
let app = express()
app.get('/say', function(req, res) {let { wd, callback } = req.queryconsole.log(wd) // HowAreYouconsole.log(callback) // showres.end(`${callback}('IAmFine')`)
})
app.listen(3000)
jsonp
属于非同源策略(跨域请求)需要服务器支持。又因为script
标签仅支持get,所以jsonp也只能对get请求跨域,不支持post。因此jsonp 适合获取资源(只读)。
另外,callback参数的传入是在后端进行了一次拼接,存在注入的可能,如果设计不当,是有可能出现安全风险的。
CORS 跨域资源共享
为了更安全的跨域资源访问,于是出现了CORS (Cross-Origin Resource Sharing 跨域资源共享)。它支持所有的请求,包含GET、POST、OPTOIN、PUT、DELETE等,通过对请求头中Origin
设置,进而实现跨域请求。
浏览器将CORS请求分成两类: 简单请求和非简单请求
只要同时满足以下两大条件,就属于简单请求。
条件一:请求方法是
HEAD/GET/POST
方法之一
条件二:HTTP头部信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
非简单请求会发出一次预检测请求,进行跨域校验,检测完毕才可真正发送请求
CORS 实现跨域:
CORS 需要浏览器和后端同时支持,浏览器会自动进行 CORS 通信,实现 CORS 通信的关键是后端。只要后端实现了 CORS,就可以实现跨域。
服务端设置 Access-Control-Allow-Origin 就可以开启 CORS
// 设置支持跨域的源,设置*为任意源,避免使用,必要时可添加多个源
header("Access-Control-Allow-Origin: http://m.zhuanzhuan.com");
// 允许携带cookie信息,禁止携带可设置false
header("Access-Control-Allow-Credentials:true");
前端设置 withCredentials 字段
// 前端设置是否带cookie
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
安全性
CORS 极大的增强了请求的安全性,但还是会有安全隐患,比如:服务端设置 Access-Control-Allow-Origin = *
;同源策略下对于部分标签的开放非同源限定;浏览器对跨域请求不接收响应也并不拦截请求;在这个背景下,出现了csrf攻击...
CSRF 跨站请求伪造
CSRF(Cross-site request forgery)跨站请求伪造,也被称为:one click attack/session riding。2000年被国外的安全人员提出,2006年开始被国内关注,2008年国内外的多个大型社区和交互网站分别爆出CSRF漏洞,如:NYTimes.com(纽约时报)、Metafilter(一个大型的BLOG网站),YouTube和百度HI......而现在,互联网上的许多站点仍对此毫无防备,以至于安全业界称CSRF为“沉睡的巨人”。
攻击者在用户已经登录目标网站之后,诱使用户访问一个攻击页面,利用目标网站对用户的信任,以用户身份在攻击页面对目标网站发起伪造用户操作的请求,达到攻击目的。
接下来图解下开头的csrf攻击事件
由此推断出 csrf的攻击特点:
csrf 攻击特点
攻击者借助于受害者的cookie等浏览器信息骗取服务器信任,攻击者拿不到cookie。
由于浏览器同源策略,攻击者拿不到响应结果,只是发起请求。
csrf攻击主要是发送修改数据请求。
常见的 csrf 攻击
投票系统,自动投票。
游戏中被迫送礼物。
交易平台,自动收货等
受到csrf攻击,或是因为一个无意的点击,也或是一次随意的浏览,因此,针对以上分析,得出以下防御策略:
CSRF防御
合理的cookie存储
登录信息及过期时间的设定考量,避免攻击方获取后可长时间攻击
Get 请求不对数据进行修改;
get 请求只做数据的查询,不做数据增删改的操作,减小被攻击的损失
请求头设置 refere, 验证 HTTP Referer 字段;
页面中请求方的域名限定,杜绝第三方网站的访问
在请求地址中添加 本次操作的唯一标识(sessionId) 并验证;
方案一:sessionId 可以是页面中生成图片验证码、短信验证码,将得到的sessionId传入请求中,并验证,这个方法操作成本有点高,会阻碍用户行为。
方案二:先通过一个请求实时获取sessionId,再将这个值传入请求中并验证。
两种方案都是同样的思路,方案二适用场景要更加广泛些
在 HTTP 头中自定义属性并验证。
属性值需要同时满足以下两点限定条件:
1、前后端要协定,保持一致;
2、每个用户有唯一的值
总结
web安全的历史长河中,从来都不是风平浪静的,每一个技术的出现都有它的使命,每一个技术的陨落也都有它的必然。浏览器诞生,开启了互联网的篇章,到如今互联网功能日益丰富,缺点也暴露的很明显,信息全球化的同时,也要考虑网络中的信息安全与隐私。
参考文章:
https://www.ruanyifeng.com/blog/2016/04/cors.html
https://segmentfault.com/a/1190000011145364#comment-area
https://www.yuque.com/suihangadam/liulanqi/pog4pf
文末福利
转发本文并留下评论,我们将抽取第 10 名留言者(依据公众号后台排序),转转纪念 T 恤一件或转转随机手办一个,可任选其一,大家快转发起来吧~
或
前端隐秘角落 - web安全的演变历程相关推荐
- Web网站架构演变历程
点击上方"后端技术精选",选择"置顶公众号" 技术文章第一时间送达! 作者:小M cnblogs.com/xiaoMzjm/p/5223799.html 前言 ...
- html页面加载完成后会触发的事件_前端隐秘角落 - 页面渲染
前言 如图所示,webkit内核浏览器的渲染过程(解析HTML,构建DOM树,解析CSS,构建CSSOM树 ,构建render树,布局layout,绘制painting),这些过程理解起来可能有些抽象 ...
- 前端隐秘角落 - HTTP请回答
HTTP请回答 「福利」 ✿✿ ヽ(°▽°)ノ ✿:文章最后有抽奖,转转纪念 T 恤一件或转转随机手办一个,走过路过不要错过哦 前言 1989年,<千千阙歌>.<梦醒时分>这些 ...
- 大型互联网架构演变历程
大型互联网架构演变历程 2. 淘宝技术这10年 2.1. 淘宝现状 高并发已经成为当前互联网企业面临的巨大挑战!例如2015年"双十一"全球狂欢节正式落下帷幕,天猫最终交易额也达到 ...
- Web网站架构演变—高并发、大数据
转 Web网站架构演变-高并发.大数据 2018年07月25日 17:27:22 gis_morningsun 阅读数:599 前言 我们以javaweb为例,来搭建一个简单的电商系统,看看这个系统可 ...
- Hybris平台Web架构模式演变:前后端分离
"前后端分离"显然已不是什么新鲜的话题,表面上看是一场架构模式的变革,但实质上是为了解决以往传统的服务端MVC设计模式的一些诟病和痛点.前后端分离带来的全新的前后端协作方式能够让专 ...
- web期末网站设计大作业:鲜花网站设计——鲜花礼品在线购物网站设计(21页) HTML+CSS+JavaScript web前端课程设计 web前端课程设计代码 web课程设计 HTML网页制作
HTML5期末大作业:鲜花网站设计--鲜花礼品在线购物网站设计(21页) HTML+CSS+JavaScript 期末作业HTML代码 学生网页课程设计期末作业下载 web网页设计制作成品 常见网页设 ...
- 什么人适合学习web前端?怎样学好web前端开发?
web前端在IT互联网行业的发展前景是非常可观的,越来越多的人都在学习web前端技术,那么什么人适合学习web前端?怎样学好web前端开发?相信大家都想了解这些问题,我们来看看下面的详细介绍. 什么人 ...
- 开发web前端_移动前端开发和web前端开发的区别?
如果说非要有区别的话应该就是开发的软件和方式不同,因为他们本来就不属于一端的东西,具体来看看下面: web前端开发 用最简单粗暴的方式来讲,就是用html + css + javascript来构建一 ...
最新文章
- 国际化困境(第二篇)
- mongo里的type_MongoDB $type 操作符
- 【原创】大数据基础之Spark(9)spark部署方式yarn/mesos
- 小程序实践(三):九宫格实现及item跳转
- 前端学习(566):margin auto机制
- ATL和ActiveX做的控件.dll和.ocx最主要的区别(摘录)
- Intent传递数据时,可以传递哪些类型数据
- jupternote不同类之间相互调用(调用ipynb文件)
- html5 语音直播,一种基于HTML5浏览器的音视频直播方法与流程
- Magnific Popup – 免费的响应式 jQuery Lightbox 插件
- oracle 恢复dmp数据,Oracle数据库使用DMP文件恢复数据
- proDAD Mercalli 2020V5.0.461注册激活码版视频稳定防抖软件
- DB2错误SQL1585N
- Crucible 安装日志
- 华笔记本linux系统方便吗,买华为国产Linux系统笔记本电脑的几个好处
- git 加速代理设置,单仓库设置代理,指定仓库设置单独代理
- mel表达式_常用表达式Mel的用法-李英江-
- python制作物联网控制软件下载_基于Python和Django框架的物联网智能设备管理系统的设计与实现...
- 电商系统中微服务体系中的分层设计和领域划分
- 超前进位加法器原理与递推式超详细推导+verilog实现与测试