擴充功能具備瀏覽器中的特殊權限,因此成為攻擊者的目標。如果擴充功能遭駭,則該擴充功能的「所有」使用者都會更容易遭受惡意和不必要的入侵。採用這些做法,即可確保擴充功能安全及其使用者。
保護開發人員帳戶
擴充功能程式碼會透過 Google 帳戶上傳及更新。如果開發人員帳戶遭駭,攻擊者可以直接向所有使用者推送惡意程式碼。建議您啟用雙重驗證 (最好使用安全金鑰) 來保護這些帳戶。
保持選擇性群組
如果使用群組發布功能,請將群組限制為信任的開發人員。不接受不明人士提出的成員資格要求。
永不使用 HTTP
要求或傳送資料時,請避免使用 HTTP 連線。假設所有 HTTP 連線都會有竊聽或包含修改內容。HTTPS 內建安全性規避大部分中間人攻擊,因此請一律優先採用。
要求最低權限
Chrome 瀏覽器會限制擴充功能存取資訊清單中明確要求的權限。擴充功能應只註冊依附的 API 和網站,藉此將權限降到最低。
限制擴充功能的權限會限制潛在攻擊者可以入侵的內容。
跨來源擷取()
擴充功能只能使用 fetch()
和 XMLHttpRequest()
從擴充功能和權限中指定的網域取得資源。請注意,服務工作站中的 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
}
如果擴充功能需要使用網站組件,或增加沙箱網頁的限制,您可以新增下列內容:
{
"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.");
});