成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

血淋淋的事實告訴你:你為什么不應該在JS文件中保存敏感信息

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

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

[[245344]]

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

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

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

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

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

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

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

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

“use strict”

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

  1. "use strict"; 
  2. var test1 = 'arka' // 有效 
  3. test2'kapı' // 引用錯誤 

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

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

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

三、從私有變量中讀取敏感數據

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

1. 重寫原生函數

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

  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()函數,然后竊取API密鑰。唯一的前提就是我們需要在我們的腳本塊后include一個外部腳本。在這個例子中,我們只是在控制臺console.log出來了這個API密鑰,但實際操作中我們還需要將其發送到我們的服務器中。

2. 定義Setter和Getter

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

  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 

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

3. 自定義枚舉器

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

  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、限制模式和在函數/塊范圍聲明變量都不一定能保證你的安全。因此,我建議大家可以從服務器端動態獲取敏感數據,而不是直接在JavaScript文件中存儲敏感數據。這樣不僅更加安全,而且還易于維護,何樂而不為?

責任編輯:趙寧寧 來源: FreeBuf
相關推薦

2018-11-12 10:14:56

網絡安全網絡安全技術周刊

2021-04-16 09:31:07

Rosetta 2安全軟件攻擊

2020-09-18 07:01:38

分頁offsetlimit

2023-04-04 08:10:40

CSS字體元素

2020-06-05 14:09:42

Kubernetes容器應用程序

2021-01-08 10:48:48

碼農編程編碼測試

2023-08-01 08:18:09

CSSUnset

2012-06-05 10:09:57

2018-09-28 16:17:20

Java 11升級Oracle

2020-03-09 13:58:19

機器人機器人流程自動化RPA

2012-05-07 17:06:29

2018-11-20 14:03:17

數據科學數據分析數據科學家

2022-12-16 09:47:29

2019-04-04 14:33:19

云計算云端企業

2015-09-28 08:57:06

Ruby APPNeo4j

2022-03-09 08:14:24

CSS容器container

2018-02-06 08:49:07

LinuxUnix命名管道

2020-06-21 21:25:14

物聯網WiFiIOT

2013-07-15 10:32:32

Windows虛擬機紅帽

2020-06-09 09:19:14

數據庫
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 操操日 | 91免费观看国产 | 91精品国产日韩91久久久久久 | 久久国产精品无码网站 | 成人欧美一区二区三区在线播放 | 亚洲天堂中文字幕 | 欧美精品一区二区三区在线 | 久久99久久99 | 日韩欧美精品 | 国产精品亚洲一区 | 国产精品亚洲综合 | 三区在线 | 在线观看日本网站 | 亚洲精品一区二区三区丝袜 | 91精品国产麻豆 | 拍真实国产伦偷精品 | 国产分类视频 | 亚洲精品自拍 | 欧美久久视频 | 午夜亚洲| 国产91在线播放精品91 | 日韩在线观看中文字幕 | 黄一区二区三区 | 一本色道久久综合亚洲精品高清 | 91大神新作在线观看 | 国产精品一区二区在线观看 | 亚洲一二三在线观看 | 欧美电影一区 | 日韩精品无码一区二区三区 | 中文字幕在线观看视频一区 | 国产精品亚洲成在人线 | 香蕉视频1024| 国产精品18hdxxxⅹ在线 | 成人欧美一区二区三区黑人孕妇 | 国产精品夜夜夜一区二区三区尤 | 久久久久99 | 亚洲精品视频在线看 | 精品一区二区在线视频 | 成人精品一区二区三区中文字幕 | 国产日韩欧美中文字幕 | 色妞av|