日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
血淋淋的事實(shí)告訴你:你為什么不應(yīng)該在JS文件中保存敏感信息

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

創(chuàng)新互聯(lián),專注為中小企業(yè)提供官網(wǎng)建設(shè)、營(yíng)銷型網(wǎng)站制作、成都響應(yīng)式網(wǎng)站建設(shè)、展示型成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)等服務(wù),幫助中小企業(yè)通過網(wǎng)站體現(xiàn)價(jià)值、有效益。幫助企業(yè)快速建站、解決網(wǎng)站建設(shè)與網(wǎng)站營(yíng)銷推廣問題。

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

 
 
 
  1. apiCall= function(type, api_key, data) { ... }  
  2. var api_key = '1391f6bd2f6fe8dcafb847e0615e5b29' 
  3. var profileInfo = apiCall('getProfile', api_key, 'all') 

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

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

為什么開發(fā)人員不應(yīng)該在JavaScript文件中嵌入敏感信息呢?原因有很多,對(duì)于經(jīng)驗(yàn)不豐富的開發(fā)人員來說,通過JavaScript文件來傳遞數(shù)據(jù)是一種非常簡(jiǎn)單的方法,因?yàn)槟憧梢詫?shù)據(jù)在服務(wù)器端生成和存儲(chǔ),然后將它們傳遞給客戶端代碼,而且這樣還可以節(jié)省一部分發(fā)送給服務(wù)器端的請(qǐng)求。但是,這種時(shí)候我們通常會(huì)忽略的一個(gè)因素就是瀏覽器的擴(kuò)展插件,有的時(shí)候?yàn)榱耸褂孟嗤拇翱趯?duì)象,它們有的時(shí)候需要直接在DOM中注入script標(biāo)簽,因?yàn)閮H僅依靠?jī)?nèi)容腳本可能無(wú)法實(shí)現(xiàn)預(yù)期的功能。

二、有沒有辦法保護(hù)變量的安全?

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

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

“use strict”

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

 
 
 
  1. "use strict"; 
  2. var test1 = 'arka' // 有效 
  3. test2= 'kap?' // 引用錯(cuò)誤 

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

 
 
 
  1. (function(){ 
  2.     "use strict"; 
  3.     //在函數(shù)范圍內(nèi)聲明變量 
  4.     var privateVar = 'Secret value';  
  5. })() 
  6. console.log(privateVar) // 引用錯(cuò)誤 

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

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

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

1. 重寫原生函數(shù)

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

 
 
 
  1. window.fetch= (url, options) => {  
  2.     console.log(`URL: ${url}, data:${options.body}`); 
  3. };  
  4. //EXTERNAL SCRIPT START  
  5. (function(){  
  6.     "use strict";  
  7.     var api_key ="1391f6bd2f6fe8dcafb847e0615e5b29"  
  8.     fetch('/api/v1/getusers', {  
  9.         method: "POST",  
  10.         body: "api_key=" + api_key  
  11.     });  
  12. })()  
  13. //EXTERNAL SCRIPT END 

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

2. 定義Setter和Getter

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

 
 
 
  1. Object.prototype.__defineSetter__('api_key',function(value){  
  2.     console.log(value);  
  3.     return this._api_key = value;  
  4. });  
  5. Object.prototype.__defineGetter__('api_key',function(){  
  6.     return this._api_key;  
  7. });  
  8. //EXTERNAL SCRIPT START  
  9. (function(){  
  10.     "use strict"  
  11.     let options = {}  
  12.     options.api_key ="1391f6bd2f6fe8dcafb847e0615e5b29"  
  13.     options.name = "Alice"  
  14.     options.endpoint ="get_user_data"  
  15.     anotherAPICall(options);  
  16. })()  
  17. //EXTERNAL SCRIPT END 

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

3. 自定義枚舉器

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

 
 
 
  1. Array.prototype[Symbol.iterator]= function() {  
  2.     let arr = this;  
  3.     let index = 0;  
  4.     console.log(arr)  
  5.     return {  
  6.         next: function() {  
  7.             return {  
  8.                 value: arr[index++],  
  9.                 done: index > arr.length  
  10.             }  
  11.         }  
  12.     }  
  13. };  
  14. //EXTERNAL SCRIPT START  
  15. (function(){  
  16.     let secretArray = ["this","contains", "an", "API", "key"];  
  17.     for (let element of secretArray) {  
  18.         doSomething(element);  
  19.     }  
  20. })()  
  21. //EXTERNAL SCRIPT END 

四、后話

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


新聞名稱:血淋淋的事實(shí)告訴你:你為什么不應(yīng)該在JS文件中保存敏感信息
鏈接地址:http://www.5511xx.com/article/dhpeoei.html