擴充功能可在瀏覽器中存取特殊權限,因此成為攻擊者的目標。如果擴充功能遭到入侵,每個使用者都可能遭到惡意和不必要的侵入。請納入這些做法,確保擴充功能和使用者安全無虞。
保護開發人員帳戶
擴充功能程式碼會透過 Google 帳戶上傳及更新。如果開發人員的帳戶遭到入侵,攻擊者可能會直接向所有使用者推送惡意程式碼。請啟用雙重驗證 (最好搭配安全金鑰),保護這些帳戶。
保留選定群組
如果使用群組發布功能,請將群組限制為信任的開發人員。請勿接受來自不明人士的會員要求。
請勿使用 HTTP
請避免在要求或傳送資料時使用 HTTP 連線。假設任何 HTTP 連線都會遭到竊聽或包含修改內容。您應一律優先使用 HTTPS,因為它內建安全機制,可規避大部分的中間人攻擊。
要求最少權限
Chrome 瀏覽器會限制擴充功能存取權,僅限於在manifest中明確要求的權限。擴充功能應只註冊所依附的 API 和網站,盡可能減少權限。
限制擴充功能的權限,可限制潛在攻擊者可利用的功能。
跨來源 fetch()
擴充功能只能使用 fetch()
和 XMLHttpRequest()
,從擴充功能和權限中指定的網域取得資源。請注意,服務 worker 中的 fetch 處理常式會攔截這兩種呼叫。
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"host_permissions": [
"https://developer.chrome.com/*",
"https://*.google.com/*"
],
"manifest_version": 3
}
上方範例中的這項擴充功能會在權限中列出 "https://developer.chrome.com/*"
和 "https://*.google.com/*"
,要求取得 developer.chrome.com 和 Google 子網域的所有內容存取權。如果擴充功能遭到入侵,仍只會獲得與符合比對模式的網站互動的權限。攻擊者只能存取 "https://user_bank_info.com"
或與 "https://malicious_website.com"
互動。
限制資訊清單欄位
在資訊清單中加入不必要的金鑰和權限會造成安全漏洞,並讓擴充功能更容易遭到檢視。將資訊清單欄位限制為擴充功能所依賴的欄位。
可外接
使用 "externally_connectable"
欄位,宣告擴充功能會與哪些外部擴充功能和網頁交換資訊。限制擴充功能可與哪些外部信任來源連線。
{
"name": "Super Safe Extension",
"externally_connectable": {
"ids": [
"iamafriendlyextensionhereisdatas"
],
"matches": [
"https://developer.chrome.com/*",
"https://*.google.com/*"
],
"accepts_tls_channel_id": false
},
...
}
網路資源
在 "web_accessible_resources"
下讓資源可供網際網路存取,這樣網站和攻擊者就能偵測到擴充功能。
{
...
"web_accessible_resources": [
{
"resources": [ "test1.png", "test2.png" ],
"matches": [ "https://web-accessible-resources-1.glitch.me/*" ]
}
]
...
}
可存取的網頁資源越多,潛在攻擊者就能利用越多管道。請盡量減少這些檔案的數量。
納入明確的內容安全政策
在資訊清單中加入延伸模組的內容安全政策,以防範跨網站指令碼攻擊。如果擴充功能只載入自身的資源,請註冊下列項目:
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": {
"extension_pages": "default-src 'self'"
},
"manifest_version": 3
}
如果擴充功能需要使用 WebAssembly,或提高沙箱頁面的限制,可以新增以下內容:
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": {
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';",
"sandboxed_pages":"script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
},
"manifest_version": 3
}
避免使用 document.write() 和 innerHTML
雖然使用 document.write()
和 innerHTML
動態建立 HTML 元素可能比較簡單,但這會讓擴充功能和擴充功能所依賴的網頁,暴露於攻擊者插入惡意指令碼的風險中。請改為手動建立 DOM 節點,並使用 innerText
插入動態內容。
function constructDOM() {
let newTitle = document.createElement('h1');
newTitle.innerText = host;
document.appendChild(newTitle);
}
謹慎使用內容指令碼
- 內容指令碼是擴充功能中唯一可直接與網頁互動的部分。因此,惡意網頁可能會操控內容指令碼所依賴的 DOM 部分,或利用令人意外的網路標準行為,例如命名項目。
- 如要與網頁的 DOM 互動,內容指令碼必須在與網頁相同的轉譯器程序中執行。這會導致內容指令碼容易遭受側通道攻擊 (例如Spectre),以及在惡意網頁入侵轉譯器程序時遭到攻擊者接管。
使用機密資料 (例如使用者私人資訊) 或可存取瀏覽器功能的 Chrome API 的作業,應在擴充功能的服務工作者中執行。避免意外將擴充功能權限公開給內容指令碼:
- 假設內容指令碼中的訊息可能是攻擊者偽造的 (例如驗證並清理所有輸入內容,並保護指令碼免受跨網站指令碼攻擊)。
- 假設傳送至內容指令碼的任何資料都可能外洩到網頁。請勿將機密資料 (例如擴充功能的機密資料、其他網站來源的資料、瀏覽記錄) 傳送至內容指令碼。
- 限制可由內容指令碼觸發的特殊權限動作範圍。禁止內容指令碼觸發對任意網址的要求,或將任意引數傳遞至擴充功能 API (例如,禁止將任意網址傳遞至
fetch()
或chrome.tabs.create()
方法)。
註冊及清理輸入內容
限制事件監聽器只接收擴充功能所需的內容、驗證傳入資料的傳送者,並清理所有輸入內容,藉此保護擴充功能免受惡意指令碼的侵害。
只有在預期來自外部網站或擴充功能的通訊時,擴充功能才應註冊 runtime.onMessageExternal
。請務必驗證寄件者是否與可信來源相符。
// The ID of an external extension
const kFriendlyExtensionId = "iamafriendlyextensionhereisdatas";
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
if (sender.id === kFriendlyExtensionId)
doSomething();
});
即使是透過擴充功能本身的 runtime.onMessage 事件傳送的訊息,也應仔細審查,確保 MessageSender 並非來自遭到入侵的內容指令碼。
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.allowedAction)
console.log("This is an allowed action.");
});