1

In browsers, use of SharedArrayBuffer is restricted to sites with the following HTTP headers because otherwise it exposes vulnerabilities to Spectre and Meltdown.

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

If you don't have access to your server, to set headers there, you can create a service worker script with those headers, and that in turn enables SharedArrayBuffer. See, for example https://github.com/gzuidhof/coi-serviceworker , specifically https://github.com/gzuidhof/coi-serviceworker/blob/master/coi-serviceworker.js

My question is whether adding the https headers via service worker exposes a security risk, because the headers are not set at the server level.

At the bottom of this article, it argues that this is not a risk, https://dev.to/stefnotch/enabling-coop-coep-without-touching-the-server-2d3n but the explanation was limited/not-convincing.

I'd appreciate an explanation to better understand whether the service-worker approach is equivalently secure, or leaves open vulnerabilities.

ultraGentle
  • 113
  • 3

1 Answers1

1

To be clear, SharedArrayBuffer is an issue because it can be used as part of Spectre/Meltdown side-channel attack exploits against the client. JavaScript running in a webpage that has access to this feature may be able to utilise it to leak information from memory. For this to be a problem, the following prerequisites must be true:

  • An attacker must run malicious JavaScript in a webpage
  • The system running the JavaScript code must be vulnerable to Spectre/Meltdown
  • That webpage must be configured with a policy that enables SharedArrayBuffer so that it can be used to aid exploitation of the vulnerability

The SharedArrayBuffer functionality is only really useful here because it provides access to a convenient segment of memory that can be shared across threads. It isn't inherently dangerous, it's just a useful primitive for cache side-channel attacks.

Cross-process attacks with Spectre/Meltdown have largely been mitigated with OS patches and microcode updates. However, the side-channel attacks can still be used to leak information from the process to itself. This is normally not a problem, because the whole program is executing with the same security context, but in a browser this is problematic because origins should not be able to access resources from each other without explicit permission.

When Cross-Origin-Opener-Policy: same-origin is used, the browser isolates the origin (webpage that set the header) in its own process and browsing context. Cross-origin resources are not loaded into the same execution context (process) as the origin, so if the cross-origin resources exploit Spectre/Meltdown they won't be able to access information from the origin.

CORS normally blocks XHR / Fetch API requests for remote resources, but it doesn't prevent you from just including a cross-origin resource in a HTML tag, like an image. Certain resources such as frames have their contents isolated from the origin, but others aren't. Some side-channel exploits utilise images and other resources to sidestep CORS in this way. The origin can protect against this to some degree using CSP, but that doesn't help a cross-origin from having its resources embedded.

The Cross-Origin-Embedder-Policy: require-corp header builds on top of the standard CORS policy and Access-Control-Allow-Origin header, expanding it to include all forms of resources instead of just scripts. This allows a cross-origin to prevent its resources (e.g. scripts and images) from being embedded in a different origin.

When a resource response combines COOP with COEP, code executing in that resource's origin is isolated and cannot load cross-origin resources, and other origins cannot load that resource as cross-origin either. Making both a requirement means that any script with access to SharedArrayBuffer will either be loaded from the origin and trusted, but executed in its own isolated context, or loaded from an explicitly trusted cross origin, and again executed in its own isolated context.

If you utilise the service workers trick to set the COOP and COEP headers as the request comes in, this doesn't negatively impact security. You're turning on the security measures that allow SharedArrayBuffer to be used safely. An attacker can still exploit Spectre/Meltdown with it, but they can only steal secrets from their own isolated execution context, which is pointless. If the cross-origin already sets the COOP and COEP HTTP response headers, they're processed and enforced by the browser before they get to your service worker, meaning that you won't be able to tamper with them.

Polynomial
  • 132,208
  • 43
  • 298
  • 379