外話:周末為了放松大家的壓力和提升大家的學習體驗,我分享了自己發現的一些前端學習視頻,大家可以和我一起在家里看看視頻輕松學習,本周視頻資源鏈接:
微信小程序視頻教程來啦,每周末都有前端視頻教程學
在現實生活中,proxy是一個被授權代表其他人的人。比如,許多州允許代理投票,這意味著你可以授權他人在選舉中代表你投票。
拿最常遇到的收快遞這一個社會行為舉例吧。很早之前,我們收發快遞都是直接和快遞員交互的,例如:
而現在,加入了代理之后,可以通過第三方替我們接收快遞,這是生活當中一個非常常見的例子,可以說代理的存在,大大的便利了“我”這個對象。即:
你很可能聽說過proxy服務器,它會接收來自你這的所有流量,代表你發送給另一端,并把響應返回給你。當你不希望請求的目的地知道你請求的具體來源時,使用proxy服務器就很有用了。所有的目標服務器看到的只是來自proxy服務器的請求。
再接近本文的主題一些,這種類型的代理和ES6 proxy要做的就很類似了,涉及到使用類(B)去包裝類(A)并攔截/控制對(A)的訪問。
當你想進行以下操作時proxy模式通常會很有用:
當一個復雜對象的多份副本須存在時,代理模式可以結合享元模式以減少內存用量。典型作法是創建一個復雜對象及多個代理者,每個代理者會引用到原本的復雜對象。而作用在代理者的運算會轉送到原本對象。一旦所有的代理者都不存在時,復雜對象會被移除。
上面是維基百科中對代理模式的一個整體的定義.而在JavaScript中代理模式的具體表現形式就是ES6中的新增對象---Proxy
ES6所提供Proxy構造函數能夠讓我們輕松的使用代理模式:
let proxy = new Proxy(target, handler);
Proxy構造函數傳入兩個參數,第一個參數target表示所要代理的對象,第二個參數handler也是一個對象用來設置對所代理的對象的行為。如果想知道Proxy的具體使用方法,可參考阮一峰的《 ECMAScript入門 - Proxy 》。
Proxy構造器可以在全局對象上訪問到。通過它,你可以有效的攔截針對對象的各種操作,收集訪問的信息,并按你的意愿返回任何值。從這個角度來說,proxy和中間件有很多相似之處。
具體來說,proxy允許你攔截許多對象上常用的方法和屬性,最常見的有get,set,apply(針對函數)和construct(針對使用new關鍵字調用的構造函數)。關于使用proxy可以攔截的方法的完整列表,請參考規范。Proxy還可以配置成隨時停止接受請求,有效的取消所有針對被代理的目標對象的訪問。這可以通過一個revoke方法實現。
1 剝離驗證邏輯
一個把Proxy用于驗證的例子,驗證一個數據源中的所有屬性都是同一類型。下面的例子中我們要確保每次給numericDataStore數據源設置一個屬性時,它的值必須是數字。
這很有意思,但有多大的可能性你會創建一個這樣的對象呢?肯定不會。。。
如果你想為一個對象上的部分或全部屬性編寫自定義的校驗規則,代碼可能會更復雜一些,但我非常喜歡Proxy可以幫你把校驗代碼與核心代碼分離開這一點。難道只有我討厭把校驗代碼和方法或類混在一起嗎?
通過這種方式,你就可以無限的擴展校驗規則而不用修改類或方法。
再說一個和校驗有關的點子。假設你想檢查傳給一個方法的參數并在傳入的參數與函數簽名不符時輸出一些有用的幫助信息。你可以通過Proxy實現此功能,而不用修改該方法的代碼。
在看一個表單驗證的例子。Proxy構造函數第二個參數中的set方法,可以很方便的驗證向一個對象的傳值。我們以一個傳統的登陸表單舉例,該表單對象有兩個屬性,分別是account和password,每個屬性值都有一個簡單和其屬性名對應的驗證方法,驗證規則如下:
下面我們來使用Proxy實現一個通用的表單驗證器
我們調用getValidateProxy方法去生成了一個代理對象userFormProxy,該對象在設置屬性的時候會根據validators的驗證規則對值進行校驗。這我們使用的是console.error拋出錯誤信息,當然我們也可以加入對DOM的事件來實現頁面中的校驗提示。
2 真正的私有屬性
在JavaScript中常見的做法是在屬性名之前或之后放一個下劃線來標識該屬性僅供內部使用。但這并不能阻止其他人讀取或修改它。
在下面的例子中,有一個我們想在api對象內部訪問的apiKey變量,但我們并不想該變量可以在對象外部訪問到。
通過使用ES6 Proxy,你可以通過若干方式來實現真實,完全的私有屬性。
首先,你可以使用一個proxy來截獲針對某個屬性的請求并作出限制或是直接返回undefined。
你還可以使用hastrap來掩蓋這個屬性的存在。
3 默默的記錄對象訪問
針對那些重度依賴資源,執行緩慢或是頻繁使用的方法或接口,你可能喜歡統計它們的使用或是性能。Proxy可以很容易的悄悄在后臺做到這一點。
注意:你不能僅僅使用applytrap來攔截方法。任何使用當你要執行某個方法時,你首先需要get這個方法。因此,如果你要攔截一個方法調用,你需要先攔截對該方法的get操作,然后攔截apply操作。
這很酷,因為你可以記錄各種各樣的信息而不用修改應用程序的代碼或是阻塞代碼執行。并且只需要在這些代碼的基礎上稍事修改就可以記錄特性函數的執行性能了。
4 給出提示信息或是阻止特定操作
假設你想阻止其他人刪除noDelete屬性,想讓調用oldMethod方法的人知道該方法已經被廢棄,或是想阻止其他人修改doNotChange屬性。以下是一種快捷的方法。
5 防止不必要的資源消耗操作--緩存代理
假設你有一個服務器接口返回一個巨大的文件。當前一個請求還在處理中,或是文件正在被下載,又或是文件已經被下載之后你不想該接口被再次請求。代理在這種情況下可以很好的緩沖對服務器的訪問并在可能的時候讀取緩存,而不是按照用戶的要求頻繁請求服務器。緩存代理可以將一些開銷很大的方法的運算結果進行緩存,再次調用該函數時,若參數一致,則可以直接返回緩存中的結果,而不用再重新進行運算。例如在采用后端分頁的表格時,每次頁碼改變時需要重新請求后端數據,我們可以將頁碼和對應結果進行緩存,當請求同一頁時就不用在進行ajax請求而是直接返回緩存中的數據。在這里我會跳過大部分代碼,但下面的例子還是足夠向你展示它的工作方式。
再列舉一個比較好理解的例子:下面我們以沒有經過任何優化的計算斐波那契數列的函數來假設為開銷很大的方法,這種遞歸調用在計算40以上的斐波那契項時就能明顯的感到延遲感。
現在我們來寫一個創建緩存代理的工廠函數:
當我們第二次調用getFibProxy(40)時,getFib函數并沒有被調用,而是直接從cache中返回了之前被緩存好的計算結果。通過加入緩存代理的方式,getFib只需要專注于自己計算斐波那契數列的職責,緩存的功能使由Proxy對象實現的。這實現了我們之前提到的單一職責原則。
6. 即時撤銷對敏感數據的訪問
Proxy支持隨時撤銷對目標對象的訪問。當你想徹底封鎖對某些數據或API的訪問時(比如,出于安全,認證,性能等原因),這可能會很有用。以下是一個使用revocable方法的簡單例子。注意當你使用它時,你不需要對Proxy方法使用new關鍵字。
到此,我們列舉了很多實用的代理模式案例,大家應該對這個設計模式有了一定的印象和理解,希望大家能在接下來的工作中繼續實踐和積累,也期待大家在評論區和我分享自己的理解和實踐過程
總結
在面向對象的編程中,代理模式的合理使用能夠很好的體現下面兩條原則:
對于代理模式 Proxy 的作用主要體現在三個方面:
1、 攔截和監視外部對對象的訪問
2、 降低函數或類的復雜度
3、 在復雜操作前對操作進行校驗或對所需資源進行管理
JavaScript設計模式之觀察者模式(Observer Pattern)
參考
今天面試的時候面試官叫我聊聊代理是怎么一回事兒,我支支吾吾磨磨蹭蹭就蹦出來了一個proxy,然后還有一個Object.defineProperty,剪不斷理還亂,腦子里就像毛線打結一樣思維纏繞,到底是怎么一回事兒,今天就寫篇文章搞定他。
代理是es6中的新特性,它可以在不修改原對象代碼的情況下,控制對原對象的訪問,這為JavaScript編程帶來了更大的靈活性和控制能力。他可以實現對對象的攔截和自定義操作,比如屬性查找、賦值、枚舉、函數調用等。
在es5中沒有代理這個操作,但是某些機制可以實現類似代理的操作,雖然沒有像es6中的代理那么靈活,但是在一些簡單的場景下可以使用。
可以通過一些間接的方式模擬代理的行為,但這通常會更復雜且不夠靈活
你可以通過閉包,在外部函數里面定義變量,在get和set方法里面引用這個變量,并且做一些額外的邏輯,返回get和set方法。
function createCounter (){
let _count = 0;
return {
getCount: function(){
//當訪問這個變量時可以做額外的邏輯
console.log('get');
return _count;
},
setCount(num){
//當修改這個變量時可以做額外的邏輯
console.log('set');
_count = num;
},
}
}
const counter = createCounter();
console.log(counter.getCount());
counter.setCount(10);
2.使用閉包和對象字面量 你可以通過閉包來封裝對目標對象的訪問,并在訪問時執行額外的邏輯。
var obj = {
_value: null,
get value() {
//當訪問這個變量時可以做額外的邏輯
console.log('get');
return this._value;
},
set value(newValue) {
//當修改這個變量時可以做額外的邏輯
console.log('set');
this._value = newValue;
}
};
console.log(obj.count);//get 0
obj.count = 10;// set
3.使用Object.defineProperty
Object.defineProperty 方法允許你精確地添加或修改對象的屬性。你可以使用它來定義getter和setter,這與在對象字面量中定義它們類似,但提供了更多的靈活性和控制能力,因為它提供了一些屬性來約束目標對象的屬性,接下里是相關語法特性。
語法
Object.defineProperty(obj, prop, descriptor)
屬性描述符
value:屬性的值。
writable:當且僅當該屬性的writable為true時,屬性的值才能被賦值運算符改變。默認為false
enumerable:當且僅當該屬性的enumerable為true時,該屬性才能夠出現在對象的枚舉屬性中。默認為false。換句話說,當使用for...in循環、Object.keys()方法、JSON.stringify()方法(除非屬性值的原始值為undefined、函數、或symbol類型的鍵)等枚舉對象屬性的方法時,該屬性會被包括在內。
configurable:當且僅當該屬性的configurable為true時,該屬性的描述符才能夠被改變,同時該屬性也能從對應的對象上被刪除。默認為false。
get:一個給屬性提供getter的方法,如果沒有getter則為undefined。當訪問該屬性時,會調用此getter函數,執行時不傳入任何參數,但是會傳入this對象(由于函數綁定,this可能是調用對象本身)。
set:一個給屬性提供setter的方法,如果沒有setter則為undefined。當屬性值被修改時,會調用此setter函數。該方法將接受唯一參數,即被賦予的新值。
如何使用Object.defineProperty模擬代理
var obj = {};
Object.defineProperty(obj, 'value', {
get: function() {
console.log('get');
return this._value;
},
set: function(newValue) {
console.log('set');
this._value = newValue;
},
enumerable: true, //該屬性可枚舉
configurable: true //該屬性可配置
});
在es6中創建代理是通過構造函數來實現的。
const proxy = new Proxy(target,handler)
它接受兩個參數:目標對象(target)和一個處理對象(handler),后者定義了要攔截并自定義的行為。
常見的handler對象中的攔截行為有:
示例
let obj = {}
let handler = {
get(target, key, receiver) {
console.log('get');
return Reflect.get(target, key, receiver);
},
set(target, key, value, receiver) {
console.log('set');
return Reflect.set(target, key, value, receiver);
}
}
const proxy = new Proxy(obj, handler);
proxy.count = 10;
console.log(proxy.count);
使用Reflect
在編寫代理的捕獲器時,通常會用到Reflect對象。ReflectAPI中的方法與捕獲器一一對應,提供了一種更直接的方式來調用目標對象上的方法。使用Reflect可以讓代碼更簡潔、易于理解,同時也避免了直接操作對象可能帶來的問題(如直接調用target[propKey]可能觸發另一個代理的捕獲器)。
代理在JavaScript中有很多應用場景
數據綁定:在vue中,代理就被用于實現數據綁定和響應式系統
權限控制:在對象中的屬性被訪問時進行權限判斷
記錄日志:在對象被訪問時記錄日志
.Burp Suite工具安裝及配置
1.Burp Suite
Burp Suite是用于Web應用安全測試、攻擊Web應用程序的集成平臺,它將各種安全工具無縫地融合在一起,以支持整個測試過程中,從最初的映射和應用程序的攻擊面分析,到發現和利用安全漏洞。
Burp Suite為這些工具設計了許多接口,以加快攻擊應用程序的過程。所有工具都共享一個請求,并能處理對應的HTTP 消息、持久性、認證、代理、日志、警報。Burp Suite結合先進的手工技術與先進的自動化,使你的工作更快,更有效,更有趣。
Burp Suite是Java編寫的,所以在使用前需要安裝JDK環境,這里不進行具體講解如何安裝JDK。作者從CSDN下載了一個版本,并能正常運行。
官方下載地址:https://portswigger.net/burp
2.安裝
安裝過程非常簡單,傻瓜式點擊“下一步”安裝。
安裝成功之后運行如下所示,點擊“Next” -> “Start Burp”顯示主界面。
3.功能
Burp Suite的模塊幾乎包含整個安全測試過程,從最初對目標程序的信息采集,到漏洞掃描及其利用,多模塊間高融合的配合,使得安全測試的過程更加高效。主要模塊如下 :
4.配置代理
(1)添加foxyproxy附件功能。
在“設置”->“添加附件”中搜索“foxyproxy”。
添加安裝該附件,如下圖所示。
點擊添加安裝。
添加成功之后,可以選擇打開FoxyProxy功能或關閉,如下圖所示。
(2)設置火狐瀏覽器Firefox本地代理。在“網絡”中設置HTTP代理為127.0.0.1,端口號為9090。
(3)接著設置Burp Suite代理,添加127.0.0.1且端口號為9090的代理,并使用它。
(4)用火狐瀏覽器打開網站則可獲取網頁相關信息。
二.Burp Suite工具Tareget
瀏該功能主要用于查看網站的目錄及元素,這里以某學校的管理系統為例,該網站的目錄顯示如下。
獲取內容包括Host、提交方法、URL、參數、狀態碼、標題、Comment、Time等,并且能夠設置對應網址的注釋Comment,如作者添加了“登錄頁面”注釋。
右下部分能顯示Request請求和Response響應信息,包括Raw、Headers、Hex、HTML等,如下圖所示。
點擊Site map左腳上部分,能夠選擇要顯示的信息,包括顯示HTML、CSS、Images等,顯示狀態碼2xx、3xx、4xx、5xx等,顯示和隱藏設置等。該功能可以按照請求類型、請求的狀態、mime類型、搜索關鍵字、文件后綴、監聽的端口等等,按個人需求去縮小需要的范圍。
比如作者設置只顯示2xx狀態碼頁面,則顯示如下圖所示。
同時,可以為不同的條目自定義設置背景顏色,代表不同的功能或類型。如果認為某個數據包比較重要,可將當前數據包設置某個醒目的顏色以提示其重要性
選中鏈接右鍵能實現更多功能,比如Spider、Scope等。
Scope主要是配合Site map做一些過濾的功能,如圖所示。
三.Burp Suite工具Proxy
Proxy主要包括Intercept、HTTP histroy 、Websockets history、Options四個標簽。
參考文章:
1.Intercept模塊
該模塊主要是控制抓取到的數據包,用于顯示修改HTTP請求及響應內容,并可以將攔截的HTTP請求快速發送至其他模塊處理。
比如當“Intercept is on”開啟時,火狐瀏覽器輸入用戶名和密碼點擊登錄,則可以看到Burp Suite攔截的用戶名和密碼。
POST /cas/login HTTP/1.1Host: xxxxx.edu.cnUser-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3Referer: http://xxxxx.edu.cn/cas/loginCookie: key_dcp_cas=nyfjdGZGmmYYdbN1fv2G349LydwzRhnrbGLqj4LMpRGd1YL3Qstl!-94055740Connection: closeContent-Type: application/x-www-form-urlencodedContent-Length: 221service=http%3A%2F%2Fi.xxxx.edu.cn%2Fdcp%2Findex.jsp&serviceName=null&loginErrCnt=0&username=20190804&password=e10adc3949ba59abbe56e057f20f883e&replace-pwd=...
在線解密,可以看到密碼為“123456”,當然,這是錯誤的用戶名和密碼。
username=20190804 password=e10adc3949ba59abbe56e057f20f883e
2.HTTP histroy模塊
該模塊將記錄經過代理服務器訪問的所有請求,即使當Intercept is off時也會記錄。包括Host(主機)、Method(請求方式)、URL(請求地址)、Params(參數)、Edited(編輯)、Status(狀態)、Length(響應字節長度)、MIME type(響應的MLME類型)、Extension(地址文件擴展名)、Title(頁面標題)、Comment(注釋)、SSL、IP(目標IP地址)、Cookies、Time(發出請求時間)、Listener port(監聽端口)。
當我們選中某個請求時,可以看他的請求包信息,同樣也可查看他的響應包信息。
雙擊某個數據包即可打開詳情,通過Previous/next功能切換到其他數據包,同時,也可將該數據包發送到其他功能模塊當中。
3.Websockets history模塊
該模塊用于記錄WebSockets的數據包,是HTML5中最強大的通信功能,定義了一個全雙工的通信信道,只需Web上的一個 Socket即可進行通信,能減少不必要的網絡流量并降低網絡延遲。
4.Options模塊
該模塊主要用于設置代理監聽、請求和響應、攔截反應、匹配和替換、ssl等。
(1)設置代理
偵聽從您的瀏覽器傳入的連接本地HTTP代理服務器。它允許您監視和攔截所有的請求和響應,并且位于BurpProxy的工作流的心臟。默認情況下,Burp默認監聽12.0.0.1地址,端口8080。
(2)配置攔截規則
置攔截的匹配規則,當Intercept request based on the following rules為選中狀態時,burpsuite會配置列表中的規則進行攔截或轉發。注意:如果該復選框未選中,那么即使Intercept is on也無法截取數據包。
如下圖所示,創建一個規則:只攔截請求頭中匹配DVWA的數據包。在實際使用過中我們可能需要創建更多更復雜的規則,來找到想要的數據包。
(3)配置攔截規則 Intercept Server Responses
攔截response并修改response中的返回值。
(4)Response Modification
用于執行響應的自動修改,可以使用這些選項來自動修改HTML應用程序響應中匹配的內容。比如,設置高亮隱藏部分,勾選unhide hidden form fields(顯示隱藏的表單,在html中type為hidden的表單)和prominently highlight unhidden fields(高亮隱藏部分)。
示例如下:
remove javascipt form validation 刪除javascript表單驗證。某些站點通過JavaScript過濾表單的內容,如字符串長度、文件后綴、字符串格式等,開啟后刪除驗證javascript。
更詳細的知識推薦讀者閱讀博客:
https://www.jianshu.com/p/73e1b0a974cc
四.Burp Suite工具暴庫示例
下面以某網址為例,進行簡單的暴庫測試。注意,它是HTTP的登錄請求。
第一步,用Burp Suite進行攔截請求,找到請求參數進行篡改。TextBoxUserName=15200000000
TextBoxPwd=111111
第二步,在界面中鼠標右鍵,在彈出菜單中選擇“Send to Intruder”(Ctrl+I),此時會將請求數據分發給Intruder模塊,并且Intruder變紅。
第三步,使用Burp Suite工具中的Intruder模塊進行破解參數配置,運行破解任務并成功破解用戶名和密碼。
(1)在Intruder模塊中選擇Positions選項,單擊“Clear”按鈕清楚相關默認參數前后的特殊符號“§”。
(2)鼠標選中請求數據頁面中的Password參數值(需要進行暴力破解的密碼值),單擊“Add§”按鈕進行位置標記。TextBoxPwd=§111111§
(3)選擇Payloads選項,單擊“Load items form file”,在彈出的對話框中選擇暴力破解密碼文件并單擊“打開”按鈕,將破解密碼列表導入。
(4)單擊“Start attack”按鈕開始破解測試。
(5)在彈出的窗口“Intruder attack”中可以根據返回長度Length的不同判斷破解是否成功,這里隱藏的密碼是“013579”,它的長度最大并且為最終密碼。注意,Length越大那么密碼吻合就越大。
也可以通過查看Response返回信息或Status返回狀態的不同信息判斷是否成功。
錯誤的密碼返回信息:
正確的密碼返回信息:
(6)通過破解的密碼嘗試登陸。
(7)如果密碼是經過MD5加密的,如上面第三部分測試的網站,則需要進行如下設置。在“Payload Processing”中點擊“Add”添加哈希MD5加密。
此時點擊攻擊如下圖所示,是經過加密的匹配。
個人建議,參考陳曉光大神的Web攻防書籍,也推薦大家閱讀。
補充知識:
在系統登錄時密碼加密流程一般是先將用戶名和密碼發送到服務器,服務器會把用戶提交的密碼經過Hash算法加密后和數據庫中存儲的加密值比對,如果加密值相同,則判定用戶提交密碼正確。
但有些網站系統的流程是在前臺瀏覽器客戶端對密碼進行Hash加密后傳輸給服務器并與數據庫加密值進行對比,如果加密至相同,則判定用戶提交密碼正確。此種流程不是很好,它會泄露密碼加密方式,導致安全隱患。
五.火狐瀏覽器HTTPS訪問之安全證書安裝
當我們想訪問HTTPS網站時,需要導入Burp Suite安裝證書并安裝,基本流程如下:
第一步,配置好瀏覽器代理。
第二步,在地址欄輸入http://burp,回車下載證書。注意這里的證書不能是零字節,不然去找破解版。
第三步,向瀏覽器中導入證書,在firefox中,選項-> 高級->證書->查看證書->證書機構。
第四步,導入證書,信任證書。
如下圖所示:
第五步,找個HTTPS網站測試即可。但作者測試百度始終沒有成果,攔截的網站也不對,無語~
參考:
https://blog.csdn.net/zyw_anquan/article/details/47904495
六.總結
寫到這里,整篇文章結束了,其實網絡安全還是挺有意思的,尤其是最后解決了一個問題之后。每一篇文章都是站在無數大神和大佬的肩膀之上,作為一個網絡安全的初學者,深深地感受到自己有太多的東西需要學習,還好態度比較端正,每天都在一步一個腳印前行。 希望這篇基礎性文章對你有所幫助,如果有錯誤或不足之處,還請海涵。后續將分享更多網絡安全方面的文章了,從零開始很難,但秀璋會一路走下去的,加油。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。