Skip to content
90 changes: 68 additions & 22 deletions files/en-us/web/security/defenses/secure_contexts/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
title: Secure contexts
slug: Web/Security/Defenses/Secure_Contexts
page-type: guide
spec-urls: https://w3c.github.io/webappsec-secure-contexts/
sidebar: security
---

A **secure context** is a `Window` or `Worker` for which certain minimum standards of authentication and confidentiality are met. Many Web APIs and features are accessible only in a secure context. The primary goal of secure contexts is to prevent [manipulator in the middle (MITM)](/en-US/docs/Web/Security/Attacks/MITM) attackers from accessing powerful APIs that could further compromise the victim of an attack.
A **secure context** is an environment such as a `Window` or `Worker` which meets a defined standard of authentication and confidentiality. Many Web APIs and features are accessible only in a secure context.

The canonical definition of a secure context, along with the rationale for restricting some web platform features to secure contexts, is given in the [Secure Contexts](https://w3c.github.io/webappsec-secure-contexts/) specification.

## Why should some features be restricted?

Expand All @@ -16,37 +17,87 @@ Some APIs on the web are very powerful, giving an attacker the ability to do the
- Get low-level access to a user's computer.
- Get access to data such as user credentials.

If these APIs were available to content that was not delivered over a secure connection, then a [manipulator in the middle (MITM)](/en-US/docs/Web/Security/Attacks/MITM) attacker would be able to access them.

## When is a context considered secure?

A context is considered secure when it meets certain minimum standards of authentication and confidentiality defined in the [Secure Contexts](https://w3c.github.io/webappsec-secure-contexts/) specification. A particular document is considered to be in a secure context when it is the [active document](https://html.spec.whatwg.org/multipage/browsers.html#active-document) of a [top-level browsing context](https://html.spec.whatwg.org/multipage/browsers.html#top-level-browsing-context) (basically, a containing window or tab) that is a secure context.
To a first approximation:

For example, even for a document delivered over TLS within an {{HTMLElement("iframe")}}, its context is **not** considered secure if it has an ancestor that was not also delivered over TLS.
- Documents are secure contexts when their resources are delivered over an [HTTPS](/en-US/docs/Web/Security/Defenses/Transport_Layer_Security) connection, or are delivered from a loopback (local) address. Framed documents must also be embedded in a document which is itself a secure context.

However, it's important to note that if a non-secure context causes a new window to be created (with or without specifying [noopener](/en-US/docs/Web/API/Window/open)), then the fact that the opener was insecure has no effect on whether the new window is considered secure. That's because the determination of whether a particular document is in a secure context is based only on considering it within the top-level browsing context with which it is associated — and not whether a non-secure context happened to be used to create it.
- Workers are secure contexts when they are created by a secure context.

Resources that are not local, to be considered secure, must meet the following criteria:
### Top-level documents

- They must be served over `https://` URLs.
- The security properties of the network channel used to deliver the resource must not be considered deprecated.
Top-level documents provide a secure context when their URL is a [potentially trustworthy URL](#potentially_trustworthy_urls).

## Potentially trustworthy origins
For example:

| URL | Secure |
| ------------------------------- | --------------------------- |
| `https://example.com` | ✅ Secure (`https` URL) |
| `http://localhost` | ✅ Secure (`localhost` URL) |
| `file:///path/to/resource.html` | ✅ Secure (`file` URL) |
| `https://example.com` | ❌ Not secure (`http` URL) |

### Framed documents

Documents in an {{htmlelement("iframe")}} provide a secure context when they are delivered from a [potentially trustworthy URL](#potentially_trustworthy_urls), and are themselves embedded in a secure context.

The means that if a top-level document from `http://example.com` embeds an `<iframe>` whose document is `https://example.com`, then the embedded document is _not_ a secure context.

| iframe URL | Parent document URL | Secure context |
| --------------------- | --------------------- | -------------- |
| `https://example.com` | `https://example.com` | ✅ Secure |
| `http://example.com` | `https://example.com` | ❌ Not secure |
| `https://example.com` | `http://example.com` | ❌ Not secure |

### Workers

#### Dedicated workers

Dedicated workers provide a secure context when their owner is a secure context.

A **potentially trustworthy origin** is one that the browser can generally trust to deliver data security, even though strictly speaking it does not meet the criteria of a secure context.
#### Shared workers

Locally-delivered resources such as those with `http://127.0.0.1`, `http://localhost`, and `http://*.localhost` URLs (for example, `http://dev.whatever.localhost/`) are not delivered using HTTPS, but they can be considered to have been delivered securely because they are on the same device as the browser. They are therefore potentially trustworthy. This is convenient for developers testing applications locally.
Shared workers follow the same rules as dedicated workers.

The same is generally true for `file://` URLs.
In addition:

Secure [WebSocket](/en-US/docs/Web/API/WebSockets_API) (`"wss://"`) URLs are also considered potentially trustworthy.
- If a shared worker is a secure context, then only other secure contexts may attach to it.
- If a shared worker is a non-secure context, then only other non-secure contexts may attach to it.

Vendor-specific URL schemes like `app://` or `chrome-extension://` are not considered potentially trustworthy by all browsers, but they may well be by the browsers whose vendors they originate from.
#### Service workers and worklets

> [!NOTE]
> Firefox 84 and later support `http://localhost` and `http://*.localhost` URLs as trustworthy origins (earlier versions did not, because `localhost` was not guaranteed to map to a local/loopback address).
Only secure contexts are allowed to register service workers, so service workers are always secure contexts.

## Potentially trustworthy URLs

A URL is potentially trustworthy if any of the following apply:

- Its value is `about:blank` or `about:srcdoc`
- Its scheme is `data`
- Its {{glossary("origin")}} is a [potentially trustworthy origin](#potentially_trustworthy_origins).

## Potentially trustworthy origins

An origin is potentially trustworthy if has:

- A scheme of `https`, `wss`, or `file`.
- A host value of `127.0.0.0/8` or `::1/128`
- A host value of `localhost` or `localhost.`
- A host value ending with `.localhost` or `.localhost.`
- A scheme that the browser considers to be authenticated

This is essentially intended to capture:

- Origins that use a secure transport across the network
- Origins that are local
- Origins that the browser considers authenticated for some other reason (for example, those used by browser extensions).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a suggestion. We need the origin, but it isn't the important thing. It would be nice to do it something like his.

Suggested change
## Potentially trustworthy URLs
A URL is potentially trustworthy if any of the following apply:
- Its value is `about:blank` or `about:srcdoc`
- Its scheme is `data`
- Its {{glossary("origin")}} is a [potentially trustworthy origin](#potentially_trustworthy_origins).
## Potentially trustworthy origins
An origin is potentially trustworthy if has:
- A scheme of `https`, `wss`, or `file`.
- A host value of `127.0.0.0/8` or `::1/128`
- A host value of `localhost` or `localhost.`
- A host value ending with `.localhost` or `.localhost.`
- A scheme that the browser considers to be authenticated
This is essentially intended to capture:
- Origins that use a secure transport across the network
- Origins that are local
- Origins that the browser considers authenticated for some other reason (for example, those used by browser extensions).
## Potentially trustworthy URLs
A URL is potentially trustworthy if any of the following apply:
- Its value is `about:blank` or `about:srcdoc`
- Its scheme is `data`
- Its {{glossary("origin")}} is a [potentially trustworthy origin](#potentially_trustworthy_origins):
- A scheme of `https`, `wss`, or `file`.
- A host value of `127.0.0.0/8` or `::1/128`
- A host value of `localhost` or `localhost.`
- A host value ending with `.localhost` or `.localhost.`
- A scheme that the browser considers to be authenticated
## Potentially trustworthy origins
A potentially trusted origin is one that uses a secure transport accross the network, a local origin, or an origin that the browser considers authenticated for some other reason (for example, those used by browser extensions).
The precise criteria are covered in the "origin" part of the previous section.

@wbamberg wbamberg Sep 11, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I see the reason you made this suggestion but I am -1 on it, for a couple of reasons.

First I like the gloss of trustworthy origin in lines 92-96, and moving it makes it inaccessible to people who come to the "Potentially trustworthy URLs" section (which as you say is most of them). I would be happy to de-bullet it though.

Second I think "The precise criteria are covered in the "origin" part of the previous section." is a bit awkward.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough!

Comment thread
wbamberg marked this conversation as resolved.
Outdated

## Feature detection

Pages can use feature detection to check whether they are in a secure context or not by using the {{domxref("Window.isSecureContext")}} or {{domxref("WorkerGlobalScope.isSecureContext")}} boolean, which is exposed on the global scope.
Pages can check whether they are in a secure context or not by using the {{domxref("Window.isSecureContext")}} or {{domxref("WorkerGlobalScope.isSecureContext")}} property.

```js
if (window.isSecureContext) {
Expand All @@ -57,13 +108,8 @@ if (window.isSecureContext) {
}
```

## Specifications

{{Specifications}}

## See also

- [Platform features restricted to secure contexts](/en-US/docs/Web/Security/Defenses/Secure_Contexts/features_restricted_to_secure_contexts) — a list of the features available only in secure contexts
- {{domxref("Window.isSecureContext")}} and {{domxref("WorkerGlobalScope.isSecureContext")}}
- <https://permission.site> — A site that allows you to check what API permission checks your browser employs, over HTTP and HTTPS
- [Strict-Transport-Security](/en-US/docs/Web/HTTP/Reference/Headers/Strict-Transport-Security) HTTP header