Skip to content

Commit

Permalink
Hint boxes improvements (#73)
Browse files Browse the repository at this point in the history
* Make hints more intuitive

* Applied new hint boxes

* New color palette

* typo

* Apply suggestions from goedi02
  • Loading branch information
terjanq committed Nov 11, 2020
1 parent 46c3542 commit 7f52379
Show file tree
Hide file tree
Showing 21 changed files with 129 additions and 134 deletions.
18 changes: 9 additions & 9 deletions content/_index.md
Expand Up @@ -12,7 +12,7 @@ Cross-Site Leaks (aka XS-Leaks, XSLeaks) are a class of vulnerabilities derived

## The principle of an XS-Leak

The fact that websites interact with each other is core to the behavior of the web. Browsers provide a wide variety of interfaces to support such interactions between different web applications. These interfaces have different security measures built on top which are intended to constrain the behavior of websites (e.g. the [Same-Origin Policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy)). XS-Leaks take advantage of small pieces of information that can leak during these interactions in order to infer sensitive information about users such as their data on other websites, operating systems they use, or internal networks they are connected to.
The fact that websites interact with each other is core to the behavior of the web. Browsers provide a wide variety of interfaces to support such interactions between different web applications. These interfaces have different security measures built on top which are intended to constrain the behavior of websites (e.g. the [Same-Origin Policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy)). XS-Leaks take advantage of small pieces of information that can leak during these interactions in order to infer sensitive information about users such as their data on other websites, operating systems they use, or internal networks they are connected to.

These pieces of information usually have a binary form and are referred to as "oracles". These oracles usually answer with *YES* or *NO* to cleverly prepared questions. For example, an oracle can be asked:

Expand All @@ -34,7 +34,7 @@ Browsers provide a wide range of different APIs that, while well-intended, can e

Websites are generally not allowed to access data on other websites. For example, *evil.com* is forbidden from explicitly reading a response from *bank.com*, but *evil.com* can attempt to load a script from *bank.com* since that was originally judged to be harmless [^harmless]. However, *evil.com* can also determine whether or not the script successfully loaded.

{{< hint info >}}
{{< hint example >}}

Suppose that *bank.com* has an API endpoint that returns data about a user's receipt for a given query.

Expand Down Expand Up @@ -89,10 +89,10 @@ In addition, we would also like to acknowledge the users who [contributed](https


## References
[^side-channel]: Side Channel Vulnerabilities on the Web - Detection and Prevention, [link](https://owasp.org/www-pdf-archive/Side_Channel_Vulnerabilities.pdf)
[^csrf]: Cross Site Request Forgery (CSRF), [link](https://owasp.org/www-community/attacks/csrf)
[^browser-features]: In some cases, these features are maintained to preserve backwards compatibility. But, in other cases, new features are added to browsers regardless of the fact that they introduce potential Cross-Site Leaks (e.g. [Scroll to Text Fragment]({{< ref "scroll-to-text-fragment.md" >}})), as the benefits are considered to outweigh the downsides.
[^harmless]: Websites being able to interact and include resources from each other is a key part of how the web works. For example, many websites allow users to post content that includes images embedded from elsewhere on the web. Fundamentally, this is an intended behavior of the web. But, over time, the downsides of this sort of interaction have become better understood.
[^old-wiki]: Browser Side Channels, [link](https://github.com/xsleaks/xsleaks/wiki/Browser-Side-Channels)
[^xs-search-first]: Cross-Site Search Attacks, [link](https://446h.cybersec.fun/xssearch.pdf)
[^spectre]: Meltdown and Spectre, [link](https://spectreattack.com/)
[^side-channel]: Side Channel Vulnerabilities on the Web - Detection and Prevention, [link](https://owasp.org/www-pdf-archive/Side_Channel_Vulnerabilities.pdf)
[^csrf]: Cross Site Request Forgery (CSRF), [link](https://owasp.org/www-community/attacks/csrf)
[^browser-features]: In some cases, these features are maintained to preserve backwards compatibility. But, in other cases, new features are added to browsers regardless of the fact that they introduce potential Cross-Site Leaks (e.g. [Scroll to Text Fragment]({{< ref "scroll-to-text-fragment.md" >}})), as the benefits are considered to outweigh the downsides.
[^harmless]: Websites being able to interact and include resources from each other is a key part of how the web works. For example, many websites allow users to post content that includes images embedded from elsewhere on the web. Fundamentally, this is an intended behavior of the web. But, over time, the downsides of this sort of interaction have become better understood.
[^old-wiki]: Browser Side Channels, [link](https://github.com/xsleaks/xsleaks/wiki/Browser-Side-Channels)
[^xs-search-first]: Cross-Site Search Attacks, [link](https://446h.cybersec.fun/xssearch.pdf)
[^spectre]: Meltdown and Spectre, [link](https://spectreattack.com/)
22 changes: 12 additions & 10 deletions content/docs/attacks/browser-features/corb.md
Expand Up @@ -19,18 +19,23 @@ weight = 2

[Cross-Origin Read Blocking]({{< ref "../../defenses/secure-defaults/corb.md" >}}) (CORB) is a web platform security feature aimed at reducing the impact of speculative side-channel attacks such as Spectre. Unfortunately, blocking certain types of requests introduced a new type of XS-Leaks that allows attackers to detect if CORB was enforced on one request, but wasn't on another. Nevertheless, the introduced XS-Leaks are much less problematic than the issues actively protected by CORB (e.g Spectre).


{{< hint info >}}
This issue is known to Chromium, and while it [might remain unfixed](https://docs.google.com/document/d/1kdqstoT1uH5JafGmRXrtKE4yVfjUVmXitjcvJ4tbBvM/edit?ts=5f2c8004), its impact is highly reduced by the [rollout of Same-Site Cookies by default](https://blog.chromium.org/2020/05/resuming-samesite-cookie-changes-in-july.html) in Chromium-based browsers.
{{< /hint >}}

## CORB & Error Events


Attackers can observe when CORB is enforced if a response returns a *CORB protected* `Content-Type` (and `nosniff`) with status code `2xx` which results in CORB stripping the body and headers from the response. Detecting this protection will allow an attacker to leak the combination of both the status code (success vs. error) and the `Content-Type` (protected by CORB or not). This allows the distinction of two possible states:
- One state results in a request being protected by CORB and the second a client error (404).
Attackers can observe when CORB is enforced if a response returns a *CORB protected* `Content-Type` (and `nosniff`) with status code `2xx` which results in CORB stripping the body and headers from the response. Detecting this protection will allow an attacker to leak the combination of both the status code (success vs. error) and the `Content-Type` (protected by CORB or not). This allows the distinction of two possible states:
- One state results in a request being protected by CORB and the second a client error (404).
- One state is protected by CORB and the second is not.

The following steps could be observed to abuse this protection with the first example:

1. An attacker can embed a cross-origin resource in a `script` tag which returns `200 OK` with `text/html` as `Content-Type` and a `nosniff` Header.
2. To protect sensitive contents from entering the attacker's process, `CORB` will replace the original response with an empty one.
3. Since an empty response is valid JavaScript, the `onerror` event won't be fired and `onload` will fire instead.
2. To protect sensitive contents from entering the attacker's process, `CORB` will replace the original response with an empty one.
3. Since an empty response is valid JavaScript, the `onerror` event won't be fired and `onload` will fire instead.
4. The attacker triggers a second request (corresponding to a second state), similar to 1., which returns something other than `200 OK`. The `onerror` event will fire.

The interesting behavior is that CORB creates a valid resource out of request which could contain something other than JavaScript (causing an error). Considering a non-CORB environment, both 1. and 4. requests would trigger an error. This introduces an XS-Leak as these situations are now distinguishable.
Expand All @@ -39,7 +44,7 @@ The interesting behavior is that CORB creates a valid resource out of request wh

CORB could also allow attackers to detect when the `nosniff` header is present in the request. This problem originated due to the fact CORB is only enforced depending on the presence of this header and some sniffing algorithms. The example below shows two distinguishable states:

1. CORB will prevent an attacker page which embeds a resource as a `script` if the resource is served with `text/html` as `Content-Type` along with the `nosniff` header.
1. CORB will prevent an attacker page which embeds a resource as a `script` if the resource is served with `text/html` as `Content-Type` along with the `nosniff` header.
2. If the resource does not set `nosniff` and CORB [fails](https://chromium.googlesource.com/chromium/src/+/master/services/network/cross_origin_read_blocking_explainer.md#what-types-of-content-are-protected-by-corb) to infer the `Content-Type` of the page (which remains `text/html`), a `SyntaxError` will be fired since the contents can't be parsed as valid JavaScript. This error can be caught by listening to `window.onerror` as `script` tags only trigger error events in [certain conditions](https://developer.mozilla.org/en-US/docs/Web/API/HTMLScriptElement).

## Defense
Expand All @@ -50,12 +55,9 @@ CORB could also allow attackers to detect when the `nosniff` header is present i
| ✔️ | ✔️ |||


{{< hint good >}}
This issue is known by Chromium, and while it [might remain unfixed](https://docs.google.com/document/d/1kdqstoT1uH5JafGmRXrtKE4yVfjUVmXitjcvJ4tbBvM/edit?ts=5f2c8004), its impact is highly reduced by the [rollout of Same-Site Cookies by default](https://blog.chromium.org/2020/05/resuming-samesite-cookie-changes-in-july.html) in Chromium-based browsers.
{{< /hint >}}

{{< hint good >}}
Developers can deploy [CORP]({{< ref "../../defenses/opt-in/corp.md" >}}) in application resources to force a protection similar to CORB that does not inspect responses to decide when to act. To prevent attackers from abusing this XS-Leak, generic XS-Leaks defense mechanisms are also effective.
{{< hint tip >}}
Developers can deploy [CORP]({{< ref "../../defenses/opt-in/corp.md" >}}) in application's subresources to force a protection similar to CORB that does not inspect responses to decide when to act. To prevent attackers from abusing this XS-Leak, generic XS-Leaks defense mechanisms are also effective.
{{< /hint >}}

## References
Expand Down
16 changes: 8 additions & 8 deletions content/docs/attacks/cache-probing.md
Expand Up @@ -45,7 +45,7 @@ Cache Probing with [Error Events]({{< ref "../attacks/error-events.md" >}}) [^2]

To invalidate a resource from the cache the attacker must force the server to return an error when fetching that subresource. There are a couple of ways to achieve this:

- A fetch request with `cache:'reload'`option that is aborted with [`AbortController.abort()`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort) before new content has been received, but after the request was initiated by the browser.
- A fetch request with `cache:'reload'`option that is aborted with [`AbortController.abort()`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort) before new content has been received, but after the request was initiated by the browser.
- A request with an [overlong referer header](https://lists.archive.carbon60.com/apache/users/316239) and `'cache':'reload'`. This might not work as browsers [capped](https://github.com/whatwg/fetch/issues/903) the length of the referrer to prevent this.
- A `POST` request with a `fetch` `no-cors`. Sometimes even in cases where an error is not returned the browser invalidates the cache.
- Request headers such as Content-Type, Accept, Accept-Language, etc that may cause the server to fail (more application dependent).
Expand All @@ -63,20 +63,20 @@ async function ifCached(url, purge = false) {
// The timeout might need to be adjusted for the attack to work properly.
// Purging content seems to take slightly less time than probing
var wait_time = (purge) ? 3 : 9;
var timeout = await setTimeout(() => {
var timeout = await setTimeout(() => {
controller.abort();
}, wait_time);
try {
// credentials option is needed for Firefox
let options = {
mode: "no-cors",
credentials: "include",
mode: "no-cors",
credentials: "include",
signal: signal
};
// If the option "cache: reload" is set, the browser will purge
// If the option "cache: reload" is set, the browser will purge
// the resource from the browser cache
if(purge) options.cache = "reload";

await fetch(url, options);
} catch (err) {
// When controller.abort() is called, the fetch will throw an Exception
Expand All @@ -88,7 +88,7 @@ async function ifCached(url, purge = false) {
// wait_time which means that the resource must have arrived from the cache
clearTimeout(timeout);
console.log("The resource is cached");

return true;
}

Expand All @@ -115,7 +115,7 @@ Currently there are no good defense mechanisms that would allow websites to full

A promising defense against this attack is [partitioning the HTTP cache]({{< ref "../defenses/secure-defaults/partitioned-cache.md" >}}) by the requesting origin. This browser provided protection prevents an attacker's origin from interfering with cached resources of other origins.

{{< hint warning >}}
{{< hint important >}}
As of November 2020, Partitioned Caches are not available in most browsers, so applications cannot rely on them.
{{< /hint >}}

Expand Down
8 changes: 4 additions & 4 deletions content/docs/attacks/experiments/scroll-to-text-fragment.md
Expand Up @@ -21,7 +21,7 @@ In early discussions for the specification of this feature it was shown that sev

## Current Issues

{{< hint info >}}
{{< hint warning >}}
These XS-Leaks require some type of markup injection on the target page.
{{< /hint >}}

Expand All @@ -30,12 +30,12 @@ During the development process of STTF new attacks and tricks to detect a fragme
- A web page that embeds an attacker-controlled `iframe` might allow the attacker to determine whether a scroll to the text has occurred. This can be done using the [`IntersectionObserver`](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) API [^2] [^3] [^4].
- If a page contains images with [Lazy Loading](https://web.dev/native-lazy-loading/) an attacker might known if a fragment navigation that included an image occurred by checking whether it was [cached in the browser]({{< ref "../cache-probing.md" >}}). This occurs because [Lazy Loading](https://web.dev/native-lazy-loading/) images are only fetched (and cached) when they appear in the viewport.

{{< hint warning >}}
{{< hint important >}}
Scroll to Text Fragment is only available in Chrome. Its [draft](https://wicg.github.io/scroll-to-text-fragment/) specification is under active discussion.
{{< /hint >}}

{{< hint good >}}
Scroll to Text Fragment XS-Leaks allow attackers to extract 1 bit of information at a time as it's only possible to observe whether a group of words is present in a page. This is because STTF matching is based on words, so attackers won't be able to leak information character by character.
{{< hint info >}}
Scroll to Text Fragment XS-Leaks allow attackers to extract 1 bit of information at a time as it's only possible to observe whether a single word exists on the page and only when a user performed some kind of interaction with the page (e.g. mouse click).
{{< /hint >}}

## Why is this a problem?
Expand Down
6 changes: 4 additions & 2 deletions content/docs/attacks/id-attribute.md
Expand Up @@ -29,15 +29,17 @@ Some web applications set `id` attributes in `focusable` elements that may lead
The below snippet presents an example way of detecting the ID attribute from another site.
```javascript
// Listen to onblur event
onblur = () => alert('Focus was lost, so there was a focusable element with the specified ID');
onblur = () => {
alert('Focus was lost, so there is a focusable element with the specified ID');
}
var ifr = document.createElement('iframe');
// If a page has a focusable element with id="x" it will gain focus
// E.g. <input id="x" value="test" />
ifr.src = 'https://example.org/#x';
document.body.appendChild(ifr);
```

{{< hint good >}}
{{< hint info >}}
The above technique doesn't seem to work in Firefox.
{{< /hint >}}

Expand Down
8 changes: 4 additions & 4 deletions content/docs/attacks/navigations.md
Expand Up @@ -55,7 +55,7 @@ setTimeout(() => {
}, 2000);
```

{{< hint warning >}}
{{< hint important >}}
This attack is only possible in Chromium-based browsers with automatic downloads enabled. The attack can't be also repeated since the user needs to close the download bar for it to be measurable again.
{{< /hint >}}

Expand Down Expand Up @@ -86,10 +86,10 @@ iframe.onload = () => {
```

{{< hint info >}}
When there is no navigation inside an iframe caused by a download attempt the iframe will not trigger an `onload` event directly. Because of that, in the example above, an outer iframe was used instead, that listens for `onload` event which triggers when subresources finished loading, including iframes.
When there is no navigation inside an iframe caused by a download attempt, the iframe will not trigger an `onload` event directly. Because of that, in the example above, an outer iframe was used instead, that listens for `onload` event which triggers when subresources finished loading, including iframes.
{{< /hint >}}

{{< hint info >}}
{{< hint important >}}
This attack will work regardless of any [Framing Protections]({{< ref "xfo" >}}), because the `X-Frame-Options` and `Content-Security-Policy` headers are ignored if `Content-Disposition: attachment` is specified.
{{< /hint >}}

Expand Down Expand Up @@ -122,7 +122,7 @@ setTimeout(() => {

A server-side redirect can be detected from a cross-origin page if the destination URL increases in size and contains an attacker controlled input (either in the form of a query string parameter or a path). The following technique relies on the fact that it is possible to induce an error in most web-servers by generating big requests parameters/paths. Since the redirect increases the size of the URL, it can be detected by sending exactly one character less than the server maximum capacity. That way if the size increases the server will respond with an error that can be detected from a cross-origin page (eg via Error Events).

{{< hint info >}}
{{< hint example >}}
An example of this attack can be seen [here](https://xsleaks.github.io/xsleaks/examples/redirect/).
{{< /hint >}}
## Cross-Origin Redirects
Expand Down

0 comments on commit 7f52379

Please sign in to comment.