日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

血淋淋的事实告诉你:你为什么不应该在JS文件中保存敏感信息

發(fā)布時間:2023/12/1 javascript 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 血淋淋的事实告诉你:你为什么不应该在JS文件中保存敏感信息 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在JavaScript文件中存儲敏感數(shù)據(jù),不僅是一種錯誤的實踐方式,而且還是一種非常危險的行為,長期以來大家都知道這一點。

而原因也非常簡單,我們可以假設(shè)你為你的用戶動態(tài)生成了一個包含API密鑰的JavaScript文件:

?

apiCall= function(type, api_key, data) { ... }

var api_key = '1391f6bd2f6fe8dcafb847e0615e5b29'

var profileInfo = apiCall('getProfile', api_key, 'all')

?

跟上述例子一樣,每當(dāng)你在全局范圍創(chuàng)建一個變量,意味著網(wǎng)站中任何一部分代碼都可以訪問到這個變量,包括你托管的其他腳本在內(nèi)。

為什么這樣做很明顯是不安全的?

為什么開發(fā)人員不應(yīng)該在JavaScript文件中嵌入敏感信息呢?原因有很多,對于經(jīng)驗不豐富的開發(fā)人員來說,通過JavaScript文件來傳遞數(shù)據(jù)是一種非常簡單的方法,因為你可以將數(shù)據(jù)在服務(wù)器端生成和存儲,然后將它們傳遞給客戶端代碼,而且這樣還可以節(jié)省一部分發(fā)送給服務(wù)器端的請求。但是,這種時候我們通常會忽略的一個因素就是瀏覽器的擴展插件,有的時候為了使用相同的窗口對象,它們有的時候需要直接在DOM中注入script標簽,因為僅僅依靠內(nèi)容腳本可能無法實現(xiàn)預(yù)期的功能。

有沒有辦法保護變量的安全?

我們之前已經(jīng)討論了全局范圍了,對于瀏覽器中的JavaScript來說,一個全局變量對于窗口對象來說是非常有用的。但是在ECMA Script5中,還有一種額外的范圍,也就是函數(shù)范圍。這也就意味著,如果我們使用var關(guān)鍵字在一個函數(shù)內(nèi)部聲明了一個變量,它就不是全局變量了。而在ECMA Script 6中又引入了另一種范圍,即塊范圍,這個范圍內(nèi)的變量使用const和let關(guān)鍵字來聲明。

這兩種關(guān)鍵字可以用來聲明塊范圍中的變量,但是我們無法修改const變量的值、如果我們沒有用這些關(guān)鍵詞來聲明變量,或者說我們在函數(shù)外部使用了var變量,我們就相當(dāng)于創(chuàng)建了一個全局變量,而這種情況并不是我們經(jīng)常想要出現(xiàn)的。

“use strict”

為了防止你不小心創(chuàng)建了全局變量,其中一種有效方法就是激活限制模式,大家可以在一個文件或函數(shù)的起始位置添加字符串“use strict”來實現(xiàn)這個功能。接下來,如果你之前沒有聲明這個變量的話,你將無法使用這個變量。

?

"use strict";

var test1 = 'arka' // 有效

test2= 'kap?' // 引用錯誤

?

我們可以在IIFE(立即調(diào)用的函數(shù)表達式)中使用這種技術(shù),IIFE可以用來創(chuàng)建一個函數(shù)范圍,但是它們會立即執(zhí)行函數(shù)主體,比如說:

?

(function(){

??? "use strict";

??? //在函數(shù)范圍內(nèi)聲明變量

??? var privateVar = 'Secret value';

})()

console.log(privateVar) // 引用錯誤

?

可能乍看過去這會是一種創(chuàng)建變量的有效方式(其內(nèi)容無法在范圍外讀取),但其實不然。雖然IIFE是一種防止全局命名空間被干擾的有效方式,但是它們并不能真正保護你的數(shù)據(jù)內(nèi)容。

從私有變量中讀取敏感數(shù)據(jù)

實際上,我們幾乎無法保證私有變量中的內(nèi)容真正的是“私有”的。原因有非常多,我們接下來會對其中的部分進行測試,雖然不夠完整,但也足夠證明給大家看,為什么我們不能在JavaScript文件中存儲敏感數(shù)據(jù)。

重寫原生函數(shù)

在下面的例子中,我們將使用一個api密鑰來向服務(wù)器端發(fā)送請求。因此,我們需要通過網(wǎng)絡(luò)并以明文數(shù)據(jù)的形式發(fā)送這個密鑰,而且現(xiàn)在在JavaScript中也沒有多少其他可選擇的方法。假設(shè)我們的代碼使用了fetch()函數(shù):

?

window.fetch= (url, options) => {

??? console.log(`URL: ${url}, data:${options.body}`);

};

//EXTERNAL SCRIPT START

(function(){

??? "use strict";

??? var api_key ="1391f6bd2f6fe8dcafb847e0615e5b29"

??? fetch('/api/v1/getusers', {

??????? method: "POST",

??????? body: "api_key=" + api_key

??? });

})()

//EXTERNAL SCRIPT END

?

你可以看到,我們可以直接重寫fetch()函數(shù),然后竊取API密鑰。唯一的前提就是我們需要在我們的腳本塊后include一個外部腳本。在這個例子中,我們只是在控制臺console.log出來了這個API密鑰,但實際操作中我們還需要將其發(fā)送到我們的服務(wù)器中。

定義Setter和Getter

私有變量中可能不僅包含字符串,還有可能包含對象或數(shù)組。對象可以有不同的屬性,在多數(shù)情況下,你可以直接設(shè)置和讀取它們的值,但是JavaScript還支持很多其他有意思的功能。比如說,你可以在一個對象的屬性被設(shè)置或被訪問的時候執(zhí)行另一個函數(shù),這里可以使用__defineSetter__和__defineGetter__函數(shù)來實現(xiàn)。如果我們在對象構(gòu)造函數(shù)的原型中使用__defineSetter__函數(shù),我們就可以輸出分配給目標對象屬性的所有值。

?

Object.prototype.__defineSetter__('api_key',function(value){

??? console.log(value);

??? return this._api_key = value;

});

Object.prototype.__defineGetter__('api_key',function(){

??? return this._api_key;

});

//EXTERNAL SCRIPT START

(function(){

??? "use strict"

??? let options = {}

??? options.api_key ="1391f6bd2f6fe8dcafb847e0615e5b29"

??? options.name = "Alice"

??? options.endpoint ="get_user_data"

??? anotherAPICall(options);

})()

//EXTERNAL SCRIPT END

?

如果分配給對象屬性的是一個API密鑰,那我們就可以直接在setter中訪問它了。另一方面,getter也可以確保我們的后續(xù)代碼能夠正確執(zhí)行。

自定義枚舉器

數(shù)組肯定是不能忽略的一個因素,如果代碼中使用了for循環(huán)來遍歷數(shù)組值,我們就可以在數(shù)組構(gòu)造器原型中定義一個自定義的枚舉器,這樣不僅可以允許我們訪問數(shù)組中的內(nèi)容,而且也不會影響原生函數(shù)的功能。

?

Array.prototype[Symbol.iterator]= function() {

??? let arr = this;

??? let index = 0;

??? console.log(arr)

??? return {

??????? next: function() {

??????????? return {

??????????????? value: arr[index++],

??????????????? done: index > arr.length

??????????? }

??????? }

??? }

};

//EXTERNAL SCRIPT START

(function(){

??? let secretArray = ["this","contains", "an", "API", "key"];

??? for (let element of secretArray) {

??????? doSomething(element);

??? }

})()

//EXTERNAL SCRIPT END

?

后話

除了本文所介紹的方法之外,攻擊者還有很多從JavaScript文件中竊取敏感信息的方法。有的情況下,使用IIFE、限制模式和在函數(shù)/塊范圍聲明變量都不一定能保證你的安全。因此,我建議大家可以從服務(wù)器端動態(tài)獲取敏感數(shù)據(jù),而不是直接在JavaScript文件中存儲敏感數(shù)據(jù)。這樣不僅更加安全,而且還易于維護,何樂而不為?

轉(zhuǎn)載于:https://www.cnblogs.com/h2zZhou/p/9770439.html

總結(jié)

以上是生活随笔為你收集整理的血淋淋的事实告诉你:你为什么不应该在JS文件中保存敏感信息的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。