.. | ||
browext-clickjacking.md | ||
browext-permissions-and-host_permissions.md | ||
browext-xss-example.md | ||
README.md |
ブラウザ拡張機能の侵入テスト方法論
htARTE(HackTricks AWS Red Team Expert)でAWSハッキングをゼロからヒーローまで学ぶ こちら!
HackTricksをサポートする他の方法:
- HackTricksで企業を宣伝したいまたはHackTricksをPDFでダウンロードしたい場合は、SUBSCRIPTION PLANSをチェックしてください!
- 公式PEASS&HackTricksグッズを入手する
- The PEASS Familyを発見し、独占的なNFTsのコレクションを見つける
- 💬 Discordグループまたはtelegramグループに参加するか、Twitter 🐦 @carlospolopmをフォローする。
- HackTricksとHackTricks CloudのgithubリポジトリにPRを提出して、あなたのハッキングテクニックを共有してください。
基本情報
ブラウザ拡張機能はJavaScriptで書かれ、ブラウザによってバックグラウンドで読み込まれます。それは独自のDOMを持ち、他のサイトのDOMとやり取りすることができます。これは他のサイトの機密性、整合性、可用性(CIA)を危険にさらす可能性があります。
主要コンポーネント
拡張機能のレイアウトは視覚化された際に最も見栄えが良く、3つのコンポーネントで構成されています。それぞれのコンポーネントを詳しく見てみましょう。
コンテンツスクリプト
各コンテンツスクリプトは単一のWebページのDOMに直接アクセスし、潜在的に悪意のある入力にさらされます。ただし、コンテンツスクリプトには、拡張機能コアにメッセージを送信する権限以外はありません。
拡張機能コア
拡張機能コアには、拡張機能のほとんどの権限/アクセスが含まれていますが、拡張機能コアはXMLHttpRequestおよびコンテンツスクリプトを介してのみWebコンテンツとやり取りできます。また、拡張機能コアはホストマシンに直接アクセスする権限はありません。
ネイティブバイナリ
拡張機能には、ユーザーの完全な権限でホストマシンにアクセスできるネイティブバイナリが含まれています。ネイティブバイナリは、Flashや他のブラウザプラグインで使用される標準のNetscape Plugin Application Programming Interface(NPAPI)を介して拡張機能コアとやり取りします。
境界
{% hint style="danger" %} ユーザーの完全な権限を取得するには、攻撃者はコンテンツスクリプトから拡張機能コアへの悪意のある入力と、拡張機能コアからネイティブバイナリへの悪意のある入力を渡すように拡張機能を説得する必要があります。 {% endhint %}
拡張機能の各コンポーネントは、強力な保護境界によって互いに分離されています。各コンポーネントは別々のオペレーティングシステムプロセスで実行されます。コンテンツスクリプトと拡張機能コアは、ほとんどのオペレーティングシステムサービスには利用できないサンドボックスプロセスで実行されます。
さらに、コンテンツスクリプトは別々のJavaScriptヒープで実行され、関連するWebページから分離されます。コンテンツスクリプトとWebページは同じ基礎となるDOMにアクセスできますが、2つはJavaScriptポインタを交換することはなく、JavaScript機能の漏洩を防ぎます。
manifest.json
Chrome拡張機能は、.crxファイル拡張子を持つZIPフォルダーです。拡張機能のコアは、フォルダーのルートにある**manifest.json
**ファイルで、レイアウト、権限、その他の構成オプションを指定します。
例:
{
"manifest_version": 2,
"name": "My extension",
"version": "1.0",
"permissions": [
"storage"
],
"content_scripts": [
{
"js": [
"script.js"
],
"matches": [
"https://example.com/*",
"https://www.example.com/*"
],
"exclude_matches": ["*://*/*business*"],
}
],
"background": {
"scripts": [
"background.js"
]
},
"options_ui": {
"page": "options.html"
}
}
content_scripts
コンテンツスクリプトは、ユーザーが一致するページに移動するたびにロードされます。この場合、**https://example.com/*
式に一致し、*://*/*/business*
**正規表現に一致しないすべてのページが該当します。これらはページ自体のスクリプトのように実行され、ページのDocument Object Model (DOM)に任意アクセスできます。
"content_scripts": [
{
"js": [
"script.js"
],
"matches": [
"https://example.com/*",
"https://www.example.com/*"
],
"exclude_matches": ["*://*/*business*"],
}
],
**include_globs
とexclude_globs
**を使用して、さらにURLを含めたり除外したりすることも可能です。
これは、ページに説明ボタンを追加するコンテンツスクリプトの例です。これは、ストレージAPIを使用して、拡張機能のストレージからmessage
値を取得するために使用されます。
chrome.storage.local.get("message", result =>
{
let div = document.createElement("div");
div.innerHTML = result.message + " <button>Explain</button>";
div.querySelector("button").addEventListener("click", () =>
{
chrome.runtime.sendMessage("explain");
});
document.body.appendChild(div);
});
このボタンがクリックされると、コンテンツスクリプトによって拡張機能ページにメッセージが送信されます。これは、storage
を含むAPIへの直接アクセスが制限されているためです。これらの例外を超える機能が必要な場合、コンテンツスクリプトが通信できる拡張機能ページにメッセージが送信されます。
{% hint style="warning" %}
ブラウザによっては、コンテンツスクリプトの機能がわずかに異なる場合があります。Chromiumベースのブラウザでは、機能のリストはChrome Developers documentationで利用可能であり、FirefoxではMDNが主要な情報源となります。
また、コンテンツスクリプトはバックグラウンドスクリプトと通信する能力を持ち、アクションを実行し、応答を返すことができます。
{% endhint %}
Chromeでコンテンツスクリプトを表示およびデバッグするには、Chromeデベロッパーツールメニューにアクセスします。オプション > その他のツール > 開発者ツールを選択するか、Ctrl + Shift + Iを押します。
デベロッパーツールが表示されたら、Sourceタブをクリックし、次にContent Scriptsタブをクリックします。これにより、さまざまな拡張機能から実行中のコンテンツスクリプトを観察し、実行フローを追跡するためのブレークポイントを設定できます。
注入されたコンテンツスクリプト
{% hint style="success" %}
コンテンツスクリプトは必須ではないことに注意してください。動的にスクリプトを注入したり、tabs.executeScript
を使用してウェブページにプログラム的に注入することも可能です。これにより、より細かい制御が可能になります。
{% endhint %}
コンテンツスクリプトをプログラム的に注入するには、スクリプトを注入するページに対してホスト権限が必要です。これらの権限は、拡張機能のマニフェスト内でそれらを要求するか、activeTabを介して一時的にセキュリティを確保することができます。
activeTabベースの拡張機能の例
{% code title="manifest.json" %}
{
"name": "My extension",
...
"permissions": [
"activeTab",
"scripting"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_title": "Action Button"
}
}
{% endcode %}
- クリック時にJSファイルをインジェクトする:
// content-script.js
document.body.style.backgroundColor = "orange";
//service-worker.js - Inject the JS file
chrome.action.onClicked.addListener((tab) => {
chrome.scripting.executeScript({
target: { tabId: tab.id },
files: ["content-script.js"]
});
});
- クリック時に関数を注入する:
//service-worker.js - Inject a function
function injectedFunction() {
document.body.style.backgroundColor = "orange";
}
chrome.action.onClicked.addListener((tab) => {
chrome.scripting.executeScript({
target : {tabId : tab.id},
func : injectedFunction,
});
});
スクリプト権限の例
// service-workser.js
chrome.scripting.registerContentScripts([{
id : "test",
matches : [ "https://*.example.com/*" ],
excludeMatches : [ "*://*/*business*" ],
js : [ "contentScript.js" ],
}]);
// Another example
chrome.tabs.executeScript(tabId, { file: "content_script.js" });
Content Scripts run_at
run_at
フィールドは、JavaScriptファイルがWebページに注入されるタイミングを制御します。推奨されるデフォルト値は"document_idle"
です。
可能な値は次のとおりです:
document_idle
:可能な限りdocument_start
:css
からのファイルの後、ただし他のDOMが構築される前や他のスクリプトが実行される前にdocument_end
:DOMが完全になった直後、ただし画像やフレームなどのサブリソースが読み込まれる前
manifest.json
を介して
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["https://*.example.com/*"],
"run_at": "document_idle",
"js": ["contentScript.js"]
}
],
...
}
**service-worker.js
**を介して
chrome.scripting.registerContentScripts([{
id : "test",
matches : [ "https://*.example.com/*" ],
runAt : "document_idle",
js : [ "contentScript.js" ],
}]);
バックグラウンド
コンテンツスクリプトによって送信されたメッセージは、バックグラウンドページによって受信されます。バックグラウンドページは、拡張機能のコンポーネントを調整する中心的な役割を果たします。特筆すべきは、バックグラウンドページが拡張機能の寿命を通じて持続し、直接的なユーザーとのやり取りなしに静かに動作します。独自のDocument Object Model(DOM)を持ち、複雑な相互作用や状態管理を可能にします。
主なポイント:
- バックグラウンドページの役割: 拡張機能の中心部として機能し、拡張機能のさまざまな部分との通信と調整を確実にします。
- 持続性: ユーザーには見えないが、拡張機能の機能性には不可欠な、常に存在するエンティティです。
- 自動生成: 明示的に定義されていない場合、ブラウザは自動的にバックグラウンドページを作成します。この自動生成されたページには、拡張機能のマニフェストで指定されたすべてのバックグラウンドスクリプトが含まれ、拡張機能のバックグラウンドタスクのシームレスな動作を保証します。
{% hint style="success" %} 明示的に宣言されていない場合にブラウザが自動的にバックグラウンドページを生成する便益により、必要なすべてのバックグラウンドスクリプトが統合され、操作されることで、拡張機能のセットアッププロセスが合理化されます。 {% endhint %}
例: バックグラウンドスクリプト:
chrome.runtime.onMessage.addListener((request, sender, sendResponse) =>
{
if (request == "explain")
{
chrome.tabs.create({ url: "https://example.net/explanation" });
}
})
It uses runtime.onMessage API to listen to messages. When an "explain"
message is received, it uses tabs API to open a page in a new tab.
To debug the background script you could go to the extension details and inspect the service worker, this will open the developer tools with the background script:
Options pages and other
Browser extensions can contain various kinds of pages:
- Action pages are displayed in a drop-down when the extension icon is clicked.
- Pages that the extension will load in a new tab.
- Option Pages: This page displays on top of the extension when clicked. In the previous manifest In my case I was able to access this page in
chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca
or clicking:
Note that these pages aren't persistent like background pages as they load dynamically content on necessity. Despite this, they share certain capabilities with the background page:
- Communication with Content Scripts: Similar to the background page, these pages can receive messages from content scripts, facilitating interaction within the extension.
- Access to Extension-Specific APIs: These pages enjoy comprehensive access to extension-specific APIs, subject to the permissions defined for the extension.
permissions
& host_permissions
permissions
and host_permissions
are entries from the manifest.json
that will indicate which permissions the browser extensions has (storage, location...) and in which web pages.
As browser extensions can be so privileged, a malicious one or one being compromised could allow the attacker different means to steal sensitive information and spy on the user.
Check how these settings work and how thye could get abused in:
{% content-ref url="browext-permissions-and-host_permissions.md" %} browext-permissions-and-host_permissions.md {% endcontent-ref %}
content_security_policy
A content security policy can be declared also inside the manifest.json
. If there is one defined, it could be vulnerable.
The default setting for browser extension pages is rather restrictive:
script-src 'self'; object-src 'self';
CSPと潜在的なバイパスに関する詳細は、以下を確認してください:
{% content-ref url="../content-security-policy-csp-bypass/" %} content-security-policy-csp-bypass {% endcontent-ref %}
web_accessible_resources
ウェブページがブラウザ拡張機能のページ(例:.html
ページ)にアクセスするためには、このページをmanifest.json
の**web_accessible_resources
**フィールドに記載する必要があります。
例:
{
...
"web_accessible_resources": [
{
"resources": [ "images/*.png" ],
"matches": [ "https://example.com/*" ]
},
{
"resources": [ "fonts/*.woff" ],
"matches": [ "https://example.com/*" ]
}
],
...
}
これらのページは次のようなURLでアクセスできます:
chrome-extension://<extension-id>/message.html
公開拡張機能では拡張機能IDにアクセスできます:
ただし、manifest.json
パラメータ**use_dynamic_url
が使用されている場合、このIDは動的になる**可能性があります。
これらのページにアクセスできることは、これらのページを潜在的に脆弱なClickJackingにする可能性があります:
{% content-ref url="browext-clickjacking.md" %} browext-clickjacking.md {% endcontent-ref %}
{% hint style="success" %} これらのページがランダムなURLではなく拡張機能のみによって読み込まれるようにすると、ClickJacking攻撃を防ぐことができます。 {% endhint %}
externally_connectable
ドキュメントによると、"externally_connectable"
マニフェストプロパティは、runtime.connectおよびruntime.sendMessageを介して拡張機能に接続できる拡張機能やWebページを宣言します。
- 拡張機能のマニフェストに**
externally_connectable
キーが宣言されていないか、"ids": ["*"]
**として宣言されている場合、すべての拡張機能が接続できますが、Webページは接続できません。 "ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]
のように特定のIDが指定されている場合、それらのアプリケーションのみが接続できます。- 一致が指定されている場合、これらのWebアプリが接続できます:
"matches": [
"https://*.google.com/*",
"*://*.chromium.org/*",
- もし**
"externally_connectable": {}
**として指定されている場合、どのアプリやウェブサイトも接続できません。
ここで指定されている拡張機能やURLが少ないほど、攻撃面が小さくなります。
{% hint style="danger" %}
externally_connectable
にXSSや接続先の脆弱性があるウェブページが示されている場合、攻撃者はContent ScriptやそのCSPを完全にバイパスし、バックグラウンドスクリプトに直接メッセージを送信できます。
したがって、これは非常に強力なバイパスです。 {% endhint %}
ウェブ ↔︎ Content Script の通信
コンテンツスクリプトが動作する環境とホストページが存在する環境はお互いに分離されており、隔離が保たれています。 この隔離状態にもかかわらず、両者はページのDocument Object Model (DOM)、共有リソースに対して相互作用する能力を持っています。 ホストページがコンテンツスクリプトと通信したり、コンテンツスクリプトを介して拡張機能と間接的に通信するためには、両者がアクセス可能なDOMを通信チャネルとして利用する必要があります。
ポストメッセージ
{% code title="content-script.js" %}
var port = chrome.runtime.connect();
window.addEventListener("message", (event) => {
// We only accept messages from ourselves
if (event.source !== window) {
return;
}
if (event.data.type && (event.data.type === "FROM_PAGE")) {
console.log("Content script received: " + event.data.text);
port.postMessage(event.data.text);
}
}, false);
{% endcode %}
{% code title="example.js" %}
document.getElementById("theButton").addEventListener("click", () => {
window.postMessage(
{type : "FROM_PAGE", text : "Hello from the webpage!"}, "*");
}, false);
{% endcode %}
セキュアなPost Message通信は、受信したメッセージの信頼性を確認する必要があります。これは以下の方法で行うことができます:
event.isTrusted
: この値は、イベントがユーザーのアクションによってトリガーされた場合にのみTrueです。- コンテンツスクリプトは、ユーザーが特定のアクションを実行した場合にのみメッセージを期待するかもしれません。
- オリジンドメイン: メッセージを期待するのは特定のドメインのみかもしれません。
- 正規表現を使用する場合は非常に注意してください。
- ソース:
received_message.source !== window
は、メッセージがコンテンツスクリプトがリッスンしている同じウィンドウから送信されたかどうかをチェックするために使用できます。
前述のチェックは、実行されていても脆弱性がある可能性があるため、次のページで潜在的なPost Messageバイパスをチェックしてください:
{% content-ref url="../postmessage-vulnerabilities/" %} postmessage-vulnerabilities {% endcontent-ref %}
Iframe
別の通信方法として、Iframe URLを介して通信する方法があります。例は以下で見つけることができます:
{% content-ref url="browext-xss-example.md" %} browext-xss-example.md {% endcontent-ref %}
DOM
これは厳密には通信方法ではありませんが、webとコンテンツスクリプトはweb DOMにアクセスできます。したがって、コンテンツスクリプトがそれから情報を読み取っている場合、web DOMを信頼している場合、webはこのデータを変更できる可能性があります(webは信頼できないため、またはwebがXSSに対して脆弱であるため)そしてコンテンツスクリプトを危険にさらす可能性があります。
ブラウザ拡張機能を危険にさらすDOMベースのXSSの例も以下で見つけることができます:
{% content-ref url="browext-xss-example.md" %} browext-xss-example.md {% endcontent-ref %}
メモリ/コード内の機密情報
ブラウザ拡張機能がメモリ内に機密情報を保存している場合、これは(特にWindowsマシンでは)ダンプされ、この情報を検索する可能性があります。
したがって、ブラウザ拡張機能のメモリは安全ではないと見なすべきであり、資格情報やニーモニックフレーズなどの機密情報は保存されてはいけません。
もちろん、コード内に機密情報を入れないでください。それは公開されることになります。
コンテンツスクリプト ↔︎ バックグラウンドスクリプト間の通信
コンテンツスクリプトは、runtime.sendMessage() または tabs.sendMessage() 関数を使用して一度だけのJSONシリアライズ可能なメッセージを送信できます。
応答を処理するには、返されたPromiseを使用します。ただし、後方互換性のために、最後の引数としてコールバックを渡すこともできます。
コンテンツスクリプトからリクエストを送信する方法は次のようになります:
(async () => {
const response = await chrome.runtime.sendMessage({greeting: "hello"});
// do something with response here, not outside the function
console.log(response);
})();
拡張機能(通常はバックグラウンドスクリプト)からリクエストを送信します。コンテンツスクリプトは、指定したタブに送信する必要があります。選択したタブのコンテンツスクリプトにメッセージを送信する方法の例:
// From https://stackoverflow.com/questions/36153999/how-to-send-a-message-between-chrome-extension-popup-and-content-script
(async () => {
const [tab] = await chrome.tabs.query({active: true, lastFocusedWindow: true});
const response = await chrome.tabs.sendMessage(tab.id, {greeting: "hello"});
// do something with response here, not outside the function
console.log(response);
})();
受信側では、メッセージを処理するためにruntime.onMessage イベントリスナーを設定する必要があります。これはコンテンツスクリプトや拡張機能ページから見た場合に同じように見えます。
// From https://stackoverflow.com/questions/70406787/javascript-send-message-from-content-js-to-background-js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
if (request.greeting === "hello")
sendResponse({farewell: "goodbye"});
}
);
例で強調されているように、sendResponse()
は同期的に実行されました。sendResponse()
を非同期に実行するために onMessage
イベントハンドラを変更するには、return true;
を組み込むことが重要です。
重要な考慮事項として、複数のページが onMessage
イベントを受信するシナリオでは、特定のイベントに対して最初に sendResponse()
を実行するページだけが効果的に応答を提供できます。同じイベントへの後続の応答は考慮されません。
新しい拡張機能を作成する際は、コールバックではなくプロミスを使用することが好ましいです。コールバックの使用に関しては、sendResponse()
関数は、同期的なコンテキスト内で直接実行される場合、またはイベントハンドラが非同期操作を示すために true
を返す場合にのみ有効と見なされます。ハンドラがいずれも true
を返さない場合や、sendResponse()
関数がメモリから削除される(ガベージコレクトされる)と、sendMessage()
関数に関連付けられたコールバックがデフォルトでトリガーされます。
ブラウザでの拡張機能の読み込み
- ブラウザ拡張機能をダウンロードして解凍します
chrome://extensions/
に移動し、開発者モード
を有効にしますアンパックされた拡張機能を読み込む
ボタンをクリックします
Firefox の場合は、about:debugging#/runtime/this-firefox
に移動し、一時的なアドオンを読み込む
ボタンをクリックします。
ストアからソースコードを取得
Chrome 拡張機能のソースコードはさまざまな方法で取得できます。以下に各オプションの詳細な説明と手順を示します。
コマンドラインを使用して ZIP 形式で拡張機能をダウンロード
Chrome 拡張機能のソースコードは、コマンドラインを使用して ZIP ファイルとしてダウンロードできます。これには、curl
を使用して特定の URL から ZIP ファイルを取得し、その後 ZIP ファイルの内容をディレクトリに展開する必要があります。以下に手順を示します:
"extension_id"
を実際の拡張機能の ID に置き換えます。- 次のコマンドを実行します:
extension_id=your_extension_id # Replace with the actual extension ID
curl -L -o "$extension_id.zip" "https://clients2.google.com/service/update2/crx?response=redirect&os=mac&arch=x86-64&nacl_arch=x86-64&prod=chromecrx&prodchannel=stable&prodversion=44.0.2403.130&x=id%3D$extension_id%26uc"
unzip -d "$extension_id-source" "$extension_id.zip"
CRX Viewerウェブサイトを使用する
CRX Viewer拡張機能を使用する
もう1つの便利な方法は、オープンソースプロジェクトであるChrome Extension Source Viewerを使用することです。Chrome Web Storeからインストールできます。ビューアのソースコードは、GitHubリポジトリで入手できます。
ローカルにインストールされた拡張機能のソースを表示する
ローカルにインストールされたChrome拡張機能も検査できます。以下の方法で行います:
chrome://version/
にアクセスし、"Profile Path"フィールドを見つけてChromeのローカルプロファイルディレクトリにアクセスします。- プロファイルディレクトリ内の
Extensions/
サブフォルダに移動します。 - このフォルダには、通常、読みやすい形式でソースコードが含まれているすべてのインストールされた拡張機能が含まれています。
拡張機能を識別するために、それらのIDを名前にマッピングできます:
about:extensions
ページで開発者モードを有効にして、各拡張機能のIDを表示します。- 各拡張機能のフォルダ内には、読みやすい形式の
name
フィールドが含まれるmanifest.json
ファイルがあり、拡張機能を識別するのに役立ちます。
ファイルアーカイバまたはアンパッカーを使用する
Chrome Web Storeに移動して、拡張機能をダウンロードします。ファイルの拡張子は.crx
になります。
ファイルの拡張子を.zip
に変更します。
WinRAR、7-Zipなどのファイルアーカイバを使用して、ZIPファイルの内容を抽出します。
Chromeの開発者モードを使用する
Chromeを開き、chrome://extensions/
に移動します。
右上の「開発者モード」を有効にします。
「パッケージ化されていない拡張機能を読み込む」をクリックします。
拡張機能のディレクトリに移動します。
これによりソースコードはダウンロードされませんが、すでにダウンロードされたり開発された拡張機能のコードを表示および変更するのに便利です。
セキュリティ監査チェックリスト
ブラウザ拡張機能は攻撃面が限られていますが、一部には脆弱性や潜在的な強化改善点が含まれている場合があります。以下は最も一般的なものです:
- 要求される**
permissions
をできるだけ制限**する host_permissions
をできるだけ制限するcontent_security_policy
を強力に使用する- 必要がない場合は**
externally_connectable
をできるだけ制限し、デフォルトで残さないように{}
**を指定する - ここでXSSや乗っ取りに脆弱なURLが言及されている場合、攻撃者は直接バックグラウンドスクリプトにメッセージを送信できます。非常に強力なバイパスです。
web_accessible_resources
をできるだけ制限する(可能であれば空にする)- **
web_accessible_resources
**がnoneでない場合は、ClickJackingをチェックする - 拡張機能からウェブページへの通信が行われている場合、通信中に引き起こされるXSSのチェックを行う
- Post Messagesが使用されている場合は、Post Messageの脆弱性をチェックする
- Content ScriptがDOMの詳細にアクセスしている場合は、それがWebによって変更された場合にXSSを導入していないかを確認する
- この通信がContent Script -> Background script通信にも関与している場合は特に注意する
- ブラウザ拡張機能の中に機密情報を保存すべきではありません
- ブラウザ拡張機能の中に機密情報を保存すべきではありません
ツール
Tarnish
- 提供されたChrome Webstoreリンクから任意のChrome拡張機能を取得します。
- manifest.json ビューア:拡張機能のマニフェストのJSON整形バージョンを表示します。
- フィンガープリント解析:web_accessible_resourcesの検出およびChrome拡張機能のフィンガープリントJavaScriptの自動生成。
- 潜在的なClickjacking解析:web_accessible_resourcesディレクティブが設定された拡張機能HTMLページの検出。これらはページの目的に応じてClickjackingの脆弱性がある可能性があります。
- 許可警告ビューア:ユーザーが拡張機能をインストールしようとすると表示されるすべてのChrome許可プロンプト警告のリストを表示します。
- 危険な機能:攻撃者によって悪用される可能性のある危険な機能の場所を表示します(例:innerHTML、chrome.tabs.executeScriptなどの機能)。
- エントリーポイント:拡張機能がユーザー/外部入力を受け入れる場所を表示します。これは拡張機能の攻撃面を理解し、悪意のあるデータを拡張機能に送信する潜在的なポイントを探すのに役立ちます。
- 危険な機能とエントリーポイントのスキャナーには、次のものが生成されたアラートに含まれます:
- アラートを引き起こした関連するコードスニペットと行。
- 問題の説明。
- アラートを引き起こしたコードを含む完全なソースファイルを表示するための「ファイルを表示」ボタン。
- アラートされたファイルのパス。
- アラートされたファイルの完全なChrome拡張機能URI。
- JavaScriptファイル内に脆弱な行がある場合、それが含まれているすべてのページのパスと、これらのページのタイプ、web_accessible_resourceのステータス。
- Content Security Policy (CSP)アナライザーおよびバイパスチェッカー:拡張機能のCSPの弱点を指摘し、ホワイトリストに登録されたCDNなどによるCSPのバイパス方法を明らかにします。
- 既知の脆弱なライブラリ:Retire.jsを使用して既知の脆弱なJavaScriptライブラリの使用をチェックします。
- 拡張機能と整形されたバージョンをダウンロードします。
- オリジナルの拡張機能をダウンロードします。
- 拡張機能の整形されたバージョン(自動整形されたHTMLおよびJavaScript)をダウンロードします。
- スキャン結果の自動キャッシュ化。拡張機能のスキャンを実行すると、最初の実行にはかなりの時間がかかりますが、2回目以降は、拡張機能が更新されていない限り、結果がキャッシュされているためほぼ即座に実行されます。
- リンク可能なレポートURL、Tarnishによって生成された拡張機能レポートへのリンクを簡単に他の人にリンクできます。
Neto
Project Netoは、FirefoxやChromeなどの一般的なブラウザ用のブラウザプラグインや拡張機能の隠れた機能を分析し解明するために考案されたPython 3パッケージです。このパッケージは、パッケージ化されたファイルを解凍して、manifest.json
、ローカライゼーションフォルダ、JavaScriptやHTMLソースファイルからこれらの機能を抽出するプロセスを自動化します。
参考文献
- この方法論の支援に感謝します @naivenom
- https://www.cobalt.io/blog/introduction-to-chrome-browser-extension-security-testing
- https://palant.info/2022/08/10/anatomy-of-a-basic-extension/
- https://palant.info/2022/08/24/attack-surface-of-extension-pages/
- https://palant.info/2022/08/31/when-extension-pages-are-web-accessible/
- https://help.passbolt.com/assets/files/PBL-02-report.pdf
- https://developer.chrome.com/docs/extensions/develop/concepts/content-scripts
- https://developer.chrome.com/docs/extensions/mv2/background-pages
- https://thehackerblog.com/kicking-the-rims-a-guide-for-securely-writing-and-auditing-chrome-extensions/
- https://gist.github.com/LongJohnCoder/9ddf5735df3a4f2e9559665fb864eac0