從 0 開始入門 Chrome Ext 安全(一) -- 瞭解一個 Chrome Ext

做者:LoRexxar'@知道創宇404實驗室
時間:2019年11月21日
原文:https://paper.seebug.org/1082/css

在2019年初,微軟正式選擇了Chromium做爲默認瀏覽器,並放棄edge的發展。並在19年4月8日,Edge正式放出了基於Chromium開發的Edge Dev瀏覽器,並提供了兼容Chrome Ext的配套插件管理。再加上國內的大小國產瀏覽器大多都是基於Chromium開發的,Chrome的插件體系愈來愈影響着廣大的人羣。html

在這種背景下,Chrome Ext的安全問題也應該受到應有的關注,《從0開始入門Chrome Ext安全》就會從最基礎的插件開發開始,逐步研究插件自己的惡意安全問題,惡意網頁如何利用插件漏洞攻擊瀏覽器等各類視角下的安全問題。chrome

第一部分咱們就主要來聊聊關於Chrome Ext的一些基礎。json

獲取一個插件的代碼

Chrome Ext的存在模式相似於在瀏覽器層新加了一層解釋器,在咱們訪問網頁的時候,插件會加載相應的html、js、css,並解釋執行。api

因此Chrome Ext的代碼也就是html、js、css這類,那咱們如何獲取插件的代碼呢?跨域

當咱們訪問擴展程序的頁面能夠得到相應的插件id
16.png瀏覽器

而後咱們能夠在https://chrome-extension-down... 中下載相應的crx包。安全

把crx更名成zip以後解壓縮就能夠了
17.pngcookie

manifest.json

在插件的代碼中,有一個重要的文件是manifest.json,在manifest.json中包含了整個插件的各類配置,在配置文件中,咱們能夠找到一個插件最重要的部分。網絡

首先是比較重要的幾個字段

  • browser_action
    這個字段主要負責擴展圖標點擊後的彈出內容,通常爲popup.html
  • content_scripts
    matches 表明scripts插入的時機,默認爲document_idle,表明頁面空閒時
    js 表明插入的scripts文件路徑
    run_at 定義了哪些頁面須要插入scripts
  • permissions
    這個字段定義了插件的權限,其中包括從瀏覽器tab、歷史紀錄、cookie、頁面數據等多個維度的權限定義
  • content_security_policy
    這個字段定義了插件頁面的CSP
    但這個字段不影響content_scripts裏的腳本
  • background
    這個字段定義插件的後臺頁面,這個頁面在默認設置下是在後臺持續運行的,只隨瀏覽器的開啓和關閉
    persistent 定義了後臺頁面對應的路徑
    page 定義了後臺的html頁面
    scripts 當值爲false時,background的頁面不會在後臺一直運行

在開始Chrome插件的研究以前,除了manifest.json的配置之外,咱們還須要瞭解一下圍繞chrome創建的插件結構。

Chrome Ext的主要展示方式
browserAction - 瀏覽器右上角
18.png

瀏覽器的右上角點擊觸發的就是mainfest.json中的browser_action

"browser_action": {
      "default_icon": "img/header.jpg",
      "default_title": "LoRexxar Tools",
      "default_popup": "popup.html"
    },

其中頁面內容來自popup.html

pageAction

pageAction和browserAction相似,只不過其中的區別是,pageAction是在知足必定的條件下才會觸發的插件,在不觸發的狀況下會始終保持灰色。

19.png

contextMenus 右鍵菜單

經過在chrome中調用chrome.contextMenus這個API,咱們能夠定義在瀏覽器中的右鍵菜單。

固然,要控制這個api首先你必須申請控制contextMenus的權限。

{"permissions": ["contextMenus"]}

通常來講,這個api會在background中被定義,由於background會一直在後臺加載。

chrome.contextMenus.create({
    title: "測試右鍵菜單",
    onclick: function(){alert('您點擊了右鍵菜單!');}
});

https://developer.chrome.com/...

override - 覆蓋頁面

chrome提供了override用來覆蓋chrome的一些特定頁面。其中包括歷史記錄、新標籤頁、書籤等...

"chrome_url_overrides":
{
    "newtab": "newtab.html",
    "history": "history.html",
    "bookmarks": "bookmarks.html"
}

好比Toby for Chrome就是一個覆蓋新標籤頁的插件

devtools - 開發者工具
chrome容許插件重構開發者工具,而且相應的操做。
20.png

插件中關於devtools的生命週期和F12打開的窗口時一致的,當F12關閉時,插件也會自動結束。

而在devtools頁面中,插件有權訪問一組特殊的API,這組API只有devtools頁面中能夠訪問。

chrome.devtools.panels:面板相關;
chrome.devtools.inspectedWindow:獲取被審查窗口的有關信息;
chrome.devtools.network:獲取有關網絡請求的信息;
{
    // 只能指向一個HTML文件,不能是JS文件
    "devtools_page": "devtools.html"
}

21.png
https://developer.chrome.com/...

option - 選項

option表明着插件的設置頁面,當選中圖標以後右鍵選項能夠進入這個頁面。

22.png

{
    "options_ui":
    {
        "page": "options.html",
        "chrome_style": true
    },
}

omnibox - 搜索建議

在chrome中,若是你在地址欄輸入非url時,會將內容自動傳到google搜索上。

omnibox就是提供了對於這個功能的魔改,咱們能夠經過設置關鍵字觸發插件,而後就能夠在插件的幫助下完成搜索了。

{
    // 向地址欄註冊一個關鍵字以提供搜索建議,只能設置一個關鍵字
    "omnibox": { "keyword" : "go" },
}

這個功能經過chrome.omnibox這個api來定義。

notifications - 提醒

notifications表明右下角彈出的提示框

chrome.notifications.create(null, {
    type: 'basic',
    iconUrl: 'img/header.jpg',
    title: 'test',
    message: 'i found you!'
});

23.png

權限體系和api

在瞭解了各種型的插件的形式以後,還有一個比較重要的就是Chrome插件相關的權限體系和api。

Chrome發展到這個時代,其相關的權限體系劃分已經算是很是細緻了,具體的細節能夠翻閱文檔。

https://developer.chrome.com/...

拋開Chrome插件的多種表現形式不談,插件的功能主要集中在js的代碼裏,而js的部分主要能夠劃分爲5種injected script、content-script、popup js、background js和devtools js.

  • injected script 是直接插入到頁面中的js,和普通的js一致,不能訪問任何擴展API.
  • content-script 只能訪問extension、runtime等幾個有限的API,也能夠訪問dom.
  • popup js 能夠訪問大部分API,除了devtools,支持跨域訪問
  • background js 能夠訪問大部分API,除了devtools,支持跨域訪問
  • devtools js 只能訪問devtools、extension、runtime等部分API,能夠訪問dom
JS 是否能訪問DOM 是否能訪問JS 是否能夠跨域
injected script 能夠訪問 能夠訪問 不能夠
content script 能夠訪問 不能夠 不能夠
popup js 不可直接訪問 不能夠 能夠
background js 不可直接訪問 不能夠 能夠
devtools js 能夠訪問 能夠訪問 不能夠

一樣的,針對這多種js,咱們也須要特殊的方式進行調試

  • injected script: 直接F12就能夠調試
  • content-script:在F12中console選擇相應的域

    24.png

  • popup js: 在插件右鍵的列表中有審查彈出內容
  • background js: 須要在插件管理頁面點擊背景頁而後調試

通訊方式

在前面介紹過各種js以後,咱們提到一個重要的問題就是,在大部分的js中,都沒有給與訪問js的權限,包括其中比較關鍵的content script.

那麼插件怎麼和瀏覽器前臺以及相互之間進行通訊呢?

- injected-script content-script popup-js background-js
injected-script - window.postMessage - -
content-script window.postMessage - chrome.runtime.sendMessage chrome.runtime.connect chrome.runtime.sendMessage chrome.runtime.connect
popup-js - chrome.tabs.sendMessage chrome.tabs.connect - chrome.extension. getBackgroundPage()
background-js - chrome.tabs.sendMessage chrome.tabs.connect chrome.extension.getViews -
devtools-js hrome.devtools.inspectedWindow.eval - chrome.runtime.sendMessage chrome.runtime.sendMessage

popup 和 background

popup和background兩個域互相直接能夠調用js而且訪問頁面的dom。

popup能夠直接用chrome.extension.getBackgroundPage()獲取background頁面的對象,而background能夠直接用chrome.extension.getViews({type:'popup'})獲取popup頁面的對象。

// background.js
function test()
{
    alert('test');
}

// popup.js
var bg = chrome.extension.getBackgroundPage();
bg.test(); // 訪問bg的函數
alert(bg.document.body.innerHTML); // 訪問bg的DOM

popupbackground 和 content js

popupbackground 和 content js之間溝通的方式主要依賴chrome.tabs.sendMessagechrome.runtime.onMessage.addListener這種有關事件監聽的交流方式。

發送方使用chrome.tabs.sendMessage,接收方使用chrome.runtime.onMessage.addListener監聽事件。

chrome.runtime.sendMessage({greeting: '發送方!'}, function(response) {
    console.log('接受:' + response);
});

接收方

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse)
{
    console.log(request, sender, sendResponse);
    sendResponse('回覆:' + JSON.stringify(request));
});

injected script 和 content-script

因爲injected script就至關於頁面內執行的js,因此它沒權限訪問chrome對象,因此他們直接的溝通方式主要是利用window.postMessage或者經過DOM事件來實現。

injected-script中:

`window.postMessage({"test": 'test!'}, '*');

content script中:

window.addEventListener("message", function(e)
{
    console.log(e.data);
}, false);`

popupbackground 動態注入js

popupbackground沒辦法直接訪問頁面DOM,可是能夠經過chrome.tabs.executeScript來執行腳本,從而實現對頁面DOM的操做。

要注意這種操做要求必須有頁面權限

"permissions": [
        "tabs", "http://*/*", "https://*/*"
    ],

js

// 動態執行JS代碼
chrome.tabs.executeScript(tabId, {code: 'document.body.style.backgroundColor="red"'});
// 動態執行JS文件
chrome.tabs.executeScript(tabId, {file: 'some-script.js'});

chrome.storage

chrome 插件還有專門的儲存位置,其中包括chrome.storage和chrome.storage.sync兩種,其中的區別是:

  • chrome.storage 針對插件全局,在插件各個位置保存的數據都會同步。
  • chrome.storage.sync 根據帳戶自動同步,不一樣的電腦登錄同一個帳戶都會同步。

插件想訪問這個api須要提早聲明storage權限。

總結

這篇文章主要描述了關於Chrome ext插件相關的許多入門知識,在談及Chrome ext的安全問題以前,咱們可能須要先了解一些關於Chrome ext開發的問題。

在下一篇文章中,咱們將會圍繞Chrome ext多個維度的安全問題進行探討,在現代瀏覽器體系中,Chrome ext到底可能會帶來什麼樣的安全問題。

re

https://www.cnblogs.com/liuxi...
https://developer.chrome.com/...

本文由 Seebug Paper 發佈,如需轉載請註明來源。

相關文章
相關標籤/搜索