Skip to main content

Avoid CSRF, XSSI, and cross-origin information leaks.


Updated

It appears in:
Safe and secure

Why should you worry about isolating your web resources?

Many web applications are vulnerable to cross-origin attacks such as cross-site request spoofing (CSRF), cross-site scripting (XSSI), time attacks, cross-origin information leaks o side channel of speculative execution (Spectrum) attacks.

Get metadata Request headers allow you to implement a robust defense-in-depth mechanism, a resource isolation policy, to protect your application against these common cross-origin attacks.

It is common that the resources exposed by a certain web application are only loaded by the application itself and not by other websites. In such cases, implementing a resource isolation policy based on get metadata request headers requires little effort while protecting the application from cross-site attacks.

Browser compatibility

Get metadata request headers are supported starting with Chrome 76 and other Chromium-based browsers, and in development in Firefox. Watch Browser compatibility for up-to-date information on browser compatibility.

Background

Many cross-site attacks are possible because the web is open by default and your application server cannot easily protect itself from communication originating from external applications. A typical cross-origin attack is Cross-Site Request Forgery (CSRF), in which an attacker lures a user to a site they control and then submits a form to the server that the user is connected to. Since the server cannot tell if the request originated from another domain (cross-site) and the browser automatically attaches cookies to cross-site requests, the server will execute the action requested by the attacker on behalf of the user.

Other cross-site attacks, such as cross-site scripting (XSSI) or cross-origin information leaks, are similar in nature to CSRF and rely on the resource load of a victim application in an attacker-controlled document. and the leakage of information about the victim's applications. Since applications cannot easily distinguish trusted requests from untrusted requests, they cannot rule out malicious traffic between sites.

Gotchas!

Aside from the resource attacks described above, window references it can also lead to cross-origin information leaks and Specter attacks. You can prevent them by setting the Cross-Origin-Opener-Policy response header to same-origin.

Introducing Fetch Metadata

Fetch Metadata Request Headers are a new web platform security feature designed to help servers defend against cross-origin attacks. By providing information about the context of an HTTP request in a set of Sec-Fetch- * headers, allow the responding server to apply security policies before processing the request. This allows developers to decide whether to accept or reject a request based on the way it was made and the context in which it will be used, allowing them to respond only to legitimate requests made by their own application.

Same origin

Requests originating from sites served by your own server (same origin) will continue to work.

same-origin-request-1058575

Cross-site

The server may reject malicious cross-site requests due to the additional context in the HTTP request provided by Sec-Fetch- * headers.

cross-origin-request-7423869

Sec-Fetch-Site

Sec-Fetch-Site tells the server which site sent the request. The browser sets this value to one of the following:

  • same-origin, if the request was made by your own application (eg. site.example)
  • same-site, if the request was made by a subdomain of your site (eg. bar.site.example)
  • none, if the request was explicitly caused by a user's interaction with the user agent (for example, by clicking on a bookmark)
  • cross-site, if the request was submitted by another website (eg. evil.example)

Sec-Fetch-Mode

Sec-Fetch-Mode indicates the mode of the request. This roughly corresponds to the type of request and allows you to distinguish resource loads from navigation requests. For example, a destination of navigate indicates a top-level navigation request while no-cors indicates resource requests such as uploading an image.

Sec-Fetch-Dest

Sec-Fetch-Dest submit a request destination (for example, if a script or a img caused the browser to request a resource).

The additional information these request headers provide is quite simple, but the additional context allows you to build powerful server-side security logic, also known as Resource Isolation Policy, with just a few lines of code.

Implement a resource isolation policy

A resource isolation policy prevents your resources from being requested by external websites. Blocking such traffic mitigates common cross-site web vulnerabilities such as CSRF, XSSI, timing attacks, and cross-origin information leaks. This policy can be enabled for all endpoints of your application and will allow all resource requests coming from your own application, as well as direct browsing (via an HTTP GET request). Endpoints that are supposed to be loaded in a cross-site context (for example, endpoints loaded using CORS) can be excluded from this logic.

Step 1: Allow requests from browsers that do not send Fetch Metadata

Since not all browsers support fetching metadata, you must allow requests that are not set Sec-Fetch- * headers checking for the presence of sec-fetch-site.

All the following examples are python code.

if not req [ 'sec-fetch-site' ] :
return True

Caution:
Since Fetch Metadata is only supported by modern browsers, it should be used as a defense-in-depth protection and not as your main line of defense.

Step 2: Allow requests started on the same site and in the browser

Any request that does not originate from a cross-origin context (such as evil.example) will be allowed. In particular, these are requests that:

  • It comes from your own application (for example, a request from the same origin where site.example requests site.example / foo.json will always be allowed).
  • It comes from your subdomains.
  • They are explicitly caused by a user's interaction with the user agent (for example, direct navigation or clicking on a bookmark, etc.).

if req [ 'sec-fetch-site' ] in ( 'same-origin' , 'same-site' , 'none' ) :
return True

Gotchas!

In case your subdomains are not completely trustworthy, you can make the policy more strict by blocking requests from subdomains by removing the same-site value.

Step 3: enable simple top-level iframing and navigation

To make sure your site can still be linked from other sites, you need to allow simple (HTTP GET) top-level navigation.

if req [ 'sec-fetch-mode' ] == 'navigate' and req . method == 'GET'
and req [ 'sec-fetch-dest' ] not in ( 'object' , 'embed' ) :
return True

Gotchas!

The above logic protects your application endpoints from being used as resources by other websites, but will allow top-level navigation and embedding (for example, loading into a

R Marketing Digital