保障帳戶安全

擴充功能可存取瀏覽器中的特殊權限,因此對攻擊者來說是極具吸引力的目標。如果擴充功能遭到入侵,所有使用者都會受到惡意和不當入侵的威脅。請採用下列做法,確保擴充功能安全無虞,並保護使用者。

保護開發人員帳戶

擴充功能程式碼會透過 Google 帳戶上傳及更新。如果開發人員的帳戶遭到入侵,攻擊者可能會直接將惡意程式碼推送給所有使用者。啟用雙重驗證 (最好使用安全金鑰),保護這些帳戶。

使用適當的成員角色

如果發布商有多位成員,請確認授予每位使用者的角色是否適當。

一律不使用 HTTP

要求或傳送資料時,請避免使用 HTTP 連線。請假設任何 HTTP 連線都會遭到竊聽或修改。HTTPS 內建安全機制,可規避大多數中間人攻擊,因此應優先使用。

要求最少的權限

Chrome 瀏覽器會限制擴充功能只能存取資訊清單中明確要求的權限。擴充功能應盡量減少權限,只註冊依附的 API 和網站。

限制擴充功能的權限,可限制潛在攻擊者可利用的項目。

跨來源 fetch()

擴充功能只能使用 fetch()XMLHttpRequest(),從擴充功能和權限中指定的網域取得資源。請注意,這兩項呼叫都會遭到 Service 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,都應在擴充功能的 Service Worker 中執行。避免不慎將擴充功能權限暴露給內容指令碼:

註冊及清理輸入內容

限制監聽器只能監聽擴充功能預期的內容、驗證傳入資料的傳送者,以及清除所有輸入內容,藉此防範惡意指令碼。

如果擴充功能預期會收到來自外部網站或擴充功能的通訊內容,才應註冊 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.");
});