如果擴充功能會侵犯隱私權,或要求的權限超出實際需求,使用者就不會安裝。對使用者的權限要求必須合理,且僅限於實作擴充功能所需的關鍵資訊。如果擴充功能會收集或傳輸任何使用者資料,就必須遵守「保護使用者隱私」政策。
請採取下列防護措施,確保擴充功能使用者身分安全,並尊重使用者隱私。
減少必要權限
擴充功能可存取的 API 會在資訊清單的 permissions 欄位中指定。授予的權限越多,攻擊者攔截資訊的管道就越多。請只列出擴充功能依附的 API,並考慮侵入性較低的選項。擴充功能要求的權限越少,使用者看到的權限警告就越少。如果警告次數不多,使用者就更有可能安裝擴充功能。
擴充功能不應要求目前不需要的權限,但未來可能會實作,藉此「確保」使用者資料的存取權。在擴充功能更新中加入新權限,並考慮將權限設為選用。
activeTab
使用主機權限插入指令碼的擴充功能通常可以改用 activeTab。activeTab 權限會授予擴充功能目前有效分頁的暫時存取權,但前提是使用者必須叫用擴充功能。使用者離開或關閉目前的分頁時,系統會中斷存取權。可做為 <all_urls> 的替代方案,適用於許多用途。
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"permissions": ["activeTab"],
"manifest_version": 3
}
安裝期間,activeTab 權限不會顯示任何警告訊息。
選擇是否提供選用權限
加入選用權限,讓使用者選擇擴充功能需要哪些功能和權限。如果某項功能對擴充功能的核心功能並非必要,請將其設為選用功能,並將 API 或網域移至 optional_permissions 欄位。
{
"name": "Very Secure Extension",
...
"optional_permissions": [ "tabs", ],
"optional_host_permissions": ["https://www.google.com/" ],
...
}
加入選用權限後,擴充功能就能在使用者啟用相關功能時,說明為何需要特定權限。擴充功能可提供選項,讓使用者啟用功能。

點選「Okay!」(好的!) 即可在 Service Worker 中觸發下列事件。
chrome.action.onClicked.addListener((event) => {
// Permissions must be requested from inside a user gesture, like a button's
// click handler.
chrome.permissions.request(
{
permissions: ["tabs", "scripting"],
origins: ['https://www.google.com/']
},
function (granted) {
// The callback argument will be true if the user granted the permissions.
if (granted) {
// doSomething();
} else {
// doSomethingElse();
}
}
);
});
接著,系統會向使用者顯示下列要求。

您也可以在擴充功能更新中實作選用權限。這樣一來,使用者就能使用新功能,且不會停用擴充功能 (如果更新時需要新的必要權限,可能會發生這種情況)。
限制及保護使用者資訊
只要求擴充功能所需的最低資料量。擴充功能向使用者索取的資訊越少,一旦遭到入侵,造成的影響就越小。
請謹慎處理所有要求的使用者資料。在已註冊網域的安全伺服器中儲存及擷取資料。一律使用 HTTPS 連線,並避免在擴充功能的用戶端保留敏感的使用者資料,因為擴充功能儲存空間不會加密。
儲存資料和無痕模式
擴充功能可以使用 storage API 儲存資料,也可以發出伺服器要求,進而儲存資料。如果擴充功能需要儲存內容,請先確認內容是否來自無痕視窗。根據預設,擴充功能不會在無痕視窗中執行。
無痕模式保證視窗不會留下任何足跡。處理無痕視窗的資料時,擴充功能應遵守這項承諾。如果擴充功能通常會儲存瀏覽記錄,請不要儲存無痕視窗的記錄。不過,擴充功能可以儲存任何視窗 (包括無痕視窗) 的設定偏好。
如要偵測視窗是否處於無痕模式,請檢查相關 tabs.Tab 或 windows.Window 物件的 incognito 屬性。
function saveTabData(tab) {
if (tab.incognito) {
return;
} else {
chrome.storage.local.set({data: tab.url});
}
}