一、為什么要做一款這樣的小插件
資料,一直在思考如何讓資料更安全的流轉和服務于客戶,圍繞這樣的想法,我們做過許多方面的擴展,我們落地了服務端的資料切片支持場景化的設計,實作了基于JDBC協議對SQL的攔截與切片,實作了在應用層的全鏈路資料庫審計方案和實作,實作了WEB端明暗水印和檔案水印等等,但這些都是在應用服務端的改造;那么圍繞以上服務端的思想產生了在端上做一些事情,分析了集團內部服務,多以WEB服務端對客戶和用戶提供便利的功能和資料使用場景,WEB服務多以依賴瀏覽器的存在進行訪問,所以就試圖把資料安全防護的方案前置到瀏覽器上,在瀏覽器上做輔助性的資料探測,可以在研發階段和測驗階段發現資料使用的安全問題,比如某個介面的回傳了明文手機號,某個頁面未使用身份資訊但是呼叫的介面回傳了等等場景...
所以我們要做一個瀏覽插件把資料安全防護能力前置到端上實作,它不會影響開發者和測驗人員...
二、解決的思路和想法
第一步說明了我們為什么要做一款這樣的小工具,這個章節就是如何去解決上面的問題和想法,
1、瀏覽器占比分析
市場上的瀏覽器chrome/firefox/safri....從市場上資料分析目前chrome瀏覽器占比份額為66.93%,基本主導了瀏覽器市場,排名第二的是MicrosoftEdge瀏覽器,根據這樣的一個結果我們優先從chrome插件去著手,
2、知識面的延伸
我們團隊側重于后端的方向研發,在前端側的能力相對來說比較弱勢特別是在瀏覽器插件又涉及到一些底層的運轉機制等;首先官方檔案去了解chrome插件開發,明確了目前chrome支持的插件版本為v2和v3,其中不好的訊息就是v2在2023年的時候會被后續的版本放棄,意味著v2和v3要同時進行,所以又去了解了一下版本的差異,兩個版本在網路攔截方面有了比較大的改動,后者變成了規則的形式,對攔截方面不是太友好,
3、想法和功能設計
要把資料安全部分防護能力前置到瀏覽器端,意味著要對當前的功能做分析和實作,首先插件能力不能對研發和測驗人員產生影響,其次使用要方便,就有了以下的四個點的想法:
第一是WEB水印能力
通過對插件機制的了解,可以在安裝插件之后,對生效的站點修改dom的結構,把水印自動的增加到頁面中,
第二個想到的是敏感的資料
應用的敏感資料來源分為三個部分:頁面渲染的資源,介面請求的資料,介面回傳的資料,圍繞這一層的構思,最終定義要實作對頁面和請求的攔截,
第三想法是對頁面的操作的事件監聽
這個的來源于某些站點會提供大量的資料,用戶在使用的時候可以直接使用把資料復制到其它資料,這樣的操作屬于用戶個人行為也不是檔案的形式,用戶在復制的程序中無法第一時間感知是否為敏感,沒有辦法做到第一時間的追蹤和防護,
第四個..其實是額外的延伸
我們目前同時也做資料流動鏈相關的專案,在專案進行的程序中發現會在前端路由與后端路由的鏈條缺失,想到瀏覽器插件的運行機制是可以通過dom的物件拿到前端頁面的路由,這樣的思路就可以填補了這塊資料鏈關系的缺失,
三、落地的路上很多坑
1、簡易邏輯圖
2、devtool的坑
在chrome插件的生命周期中,在background能監聽請求發出、回傳等事件,一般能獲取的事件如下:
// web請求監聽,最后一個引數表示阻塞式,需單獨宣告權限:webRequestBlocking
chrome.webRequest.onBeforeRequest.addListener(details => {
// cancel 表示取消本次請求
if(details.type == 'image' || details.type === 'medis') return {cancel: false};
}, {urls: ["<all_urls>"]});
//ajax生命周期開始
chrome.webRequest.onBeforeRequest.addListener(details => {
console.log('onBeforeRequest', details);
}, { urls: ["*://*.jd.com/**"] });
chrome.webRequest.onBeforeSendHeaders.addListener(details => {
console.log('onBeforeSendHeaders', details)
},
{ urls: ["*://*.jd.com/**"] },
['blocking', 'requestHeaders', 'extraHeaders']
);
// 可以攔截ajax
chrome.webRequest.onResponseStarted.addListener(details => {
console.log('onResponseStarted', details);
}, {urls: ["*://*.jd.com/**"]});
// 請求完成,但是取不到response結果
chrome.webRequest.onCompleted.addListener(details => {
console.log('onCompleted', details);
}, {urls: ["*://*.jd.com/**"]
該方式無法拿到response內容,從網上常見的解決方案,是給瀏覽器插件添加devtools_page模塊,然后在devtools的頁面添加request結束事件,如下:
chrome.devtools.network.onRequestFinished.addListener(
function(request) {
//request 包含請求回應資料,如:url,回應內容等
//request.request.url 介面 的url
//request.getContent 介面回傳的內容
}
);
但是該方式有個問題,就是想要觸發devtools的頁面內容,需要在頁面按F12呼出瀏覽器的控制臺,這個體驗就很一般,所以devtools這種形式更像是為開發人員提供debug工具時引入的,
3、xhr/fetch
因為上文使用兩種方式的局限性,所以考慮重寫xhr,然后在頁面加載時進行注入替換,重寫xhr的方法如下:
(function () {
var open = XMLHttpRequest.prototype.open;
var send = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function (body) {
this["hookQuery"] = body;
send.apply(this, arguments);
};
XMLHttpRequest.prototype.open = function () {
this.addEventListener("load", function () {
if (this.responseType === "" || this.responseType === "text") {
window.dispatchEvent(
new CustomEvent("pageScript", {
...
})
);
}
});
open.apply(this, arguments);
};
})()
主要改寫了原有send方法和open方法,在send時,將請求的引數記錄到xhr物體的一個屬性里,然后在請求觸發并回傳(load事件)后,將請求的引數、回應的回傳內容,通過事件發送出去,事件會在content_scripts進行監聽和處理,content_scripts部分代碼如下:
// 加載重寫的xhr所在js檔案,然后注入到當前頁面的document中,這樣業務的頁面會加載這段js
var hook = document.createElement("script");
hook.src = https://www.cnblogs.com/Jcloud/p/chrome.runtime.getURL("script/hook.js");
hook.onload = function () {
this.remove();
};
(document.head || document.documentElement).appendChild(hook);
// 監聽xhr發送過來的訊息
window.addEventListener(
"pageScript",
function (event) {
// 處理邏輯
},
false
);
五、效果演示
六、未完待續
第一版的功能以敏感資料防護為主導線,后續會增加資料安全其它的防護和感知能力,從端上協助業務解決資料安全的風險
作者:CCO體系 郝帥衛
來源:京東云開發者社區
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/553835.html
標籤:其他
上一篇:【智能軟體安全】上海道寧為您帶來智能軟體安全平臺——?Veracode,幫助您全面地保護您構建和管理地應用程式
下一篇:返回列表
