Skip to content

Technical review: Document local network access#43575

Open
chrisdavidmills wants to merge 2 commits intomdn:mainfrom
chrisdavidmills:local-network-access
Open

Technical review: Document local network access#43575
chrisdavidmills wants to merge 2 commits intomdn:mainfrom
chrisdavidmills:local-network-access

Conversation

@chrisdavidmills
Copy link
Copy Markdown
Contributor

Description

Between versions 142 and 145, Chrome enables support for various features of the Local Network Access spec. See https://chromestatus.com/feature/5152728072060928 and https://chromestatus.com/feature/5068298146414592.

Specifically, these are:

  • The targetAddressSpace Request property, and the equivalent RequestInit property.
  • The local-network-access permission/Permissions-Policy directive.
  • The more granular local-network and loopback-network permissions/Permissions-Policy directives.

This PR:

  • Adds reference pages for the above features.
  • Adds a new "Local network access" guide inside the MDN security section (I didn't add a regular API page for this, because it doesn't really feel like it warrants an API page — it is just a single property and some new permissions, in terms of web developer footprint.)
  • Adds links to the guide from several related places.

Motivation

Additional details

Related issues and pull requests

@chrisdavidmills chrisdavidmills requested review from a team as code owners March 25, 2026 15:14
@chrisdavidmills chrisdavidmills requested review from hamishwillee and removed request for a team March 25, 2026 15:14
@github-actions github-actions bot added Content:HTML Hypertext Markup Language docs Content:WebAPI Web API docs Content:HTTP HTTP docs Content:Security Security docs labels Mar 25, 2026
@chrisdavidmills chrisdavidmills changed the title Document local network access Technical review: Document local network access Mar 25, 2026
@github-actions github-actions bot added the size/m [PR only] 51-500 LoC changed label Mar 25, 2026
Local network access defines three different **address spaces**, which all network addresses are categorised under:

- Local
- : A local address is only accessible on the local network: Its target will differ on different networks. For example, `http://192.168.0.1`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
- : A local address is only accessible on the local network: Its target will differ on different networks. For example, `http://192.168.0.1`.
- : A local address is only accessible on the local network: Its target will differ on different networks. For example, `192.168.0.1`.

I think better to keep these as just IP addresses, rather than URLs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

OK. I've fixed all these across the PR in my next commit.

- Loopback
- : A loopback address is only accessible on the local device: Its target will differ on every device. For example, `127.0.0.1`, which is generally known as `localhost`.
- Public
- : A public web address is available from anywhere on the internet: Its target is the same for all devices globally on the IP network. For example, `https://example.com`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
- : A public web address is available from anywhere on the internet: Its target is the same for all devices globally on the IP network. For example, `https://example.com`.
- : A public address is available from anywhere on the internet: Its target is the same for all devices globally on the Internet. For example, `104.18.27.120` (the IP address of `example.com`).

Thinking about how to make this more consistent with the other address spaces... Maybe remove "web" as this is a lower layer concept (don't want to confuse with URLs). Swap domain name with the public IP address it resolves to.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I like this. I've tweaked it slightly, to:

A public address is available from anywhere on the internet; its target is the same for all devices globally. For example, 104.18.27.120 (the IP address of example.com).

I'll go through and make sure similar fixes are made across the PR.

// loopback
```

This is needed in cases where a URL is a public domain address, but ends up resolving to a local network address, such as `http://example.com`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Do we want this example to be a real world case of a "public domain name that resolves to a local IP address"? One such case is routerlogin.net when the user is behind an Netgear router; another is plex.direct URLs (like 192-168-0-7.###.plex.direct). Or we could still use the example domain but make it a bit more obviously a non-real-world example like internal.example.com?

Suggested change
This is needed in cases where a URL is a public domain address, but ends up resolving to a local network address, such as `http://example.com`.
This is needed in cases where a URL is a public domain address, but ends up resolving to a local network address, such as `http://internal.example.com`.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've updated it to http://internal.example.com — we tend to avoid using "real" examples that we don't control, with example.com being the exception.


Local network access was originally implemented with the {{httpheader('Permissions-Policy/local-network-access','local-network-access')}} permission, which was used to control network requests to both local and loopback addresses together. This was updated to the more granular {{httpheader('Permissions-Policy/local-network','local-network')}} and {{httpheader('Permissions-Policy/loopback-network','loopback-network')}} permissions, which you should use going forward.

However, the `local-network-access` permission continues to be supported for backwards-compatibility, as an alias of `local-network` and `loopback-network`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
However, the `local-network-access` permission continues to be supported for backwards-compatibility, as an alias of `local-network` and `loopback-network`.
However, the `local-network-access` permission continues to be supported for backwards-compatibility in Chromium, as an alias of `local-network` and `loopback-network`.

The alias is only supported in Chromium. Firefox prefers to not need to support it, and we will hopefully be able to remove it entirely 🤞

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Makes sense. I've tweaked it to the following:

However, the local-network-access permission continues to be supported for backwards-compatibility where already implemented, as an alias of local-network and loopback-network.

Does that work for you?

We're strict about not including specific browser support info in content (rather than in the browser compat data), but this should be allowed. There is no compat data at that link yet, but this will change when mdn/browser-compat-data#29331 is merged.

Once you remove this permission, we should be able to delete this section and mark the compat data with the removal version, and we should be all set.

- : Controls whether the current document is allowed to make network requests to local addresses.

- {{httpheader('Permissions-Policy/local-network-access','local-network-access')}} {{Experimental_Inline}}
- : Controls whether the current document is allowed to make network requests to local and loopback addresses. This policy directive is an alias for the more granular `local-network` and `loopback-network` directives.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
- : Controls whether the current document is allowed to make network requests to local and loopback addresses. This policy directive is an alias for the more granular `local-network` and `loopback-network` directives.
- : Controls whether the current document is allowed to make network requests to local and loopback addresses. This policy directive is an alias for the more granular `local-network` and `loopback-network` directives. Only supported in Chromium browsers.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Similarly as to the main article, the alias is only supported by Chromium (and we hope to remove it eventually).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

See above comment — readers can look at the compat data for the directive to see the support story.


The HTTP {{HTTPHeader("Permissions-Policy")}} header `local-network` directive controls whether the current document is allowed to make network requests to local addresses.

A local address is only accessible on the local network: Its target will differ on different networks. For example, `http://192.168.0.1`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
A local address is only accessible on the local network: Its target will differ on different networks. For example, `http://192.168.0.1`.
A local address is only accessible on the local network: Its target will differ on different networks. For example, `192.168.0.1`.

Same as in main article, prefer using IP address form over URL form I think

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

updated


{{SeeCompatTable}}

The HTTP {{HTTPHeader("Permissions-Policy")}} header `local-network-access` directive controls whether the current document is allowed to make network requests to local and loopback addresses. This policy directive is an alias for the newer {{httpheader('Permissions-Policy/local-network','local-network')}} and {{httpheader('Permissions-Policy/loopback-network','loopback-network')}} directives.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
The HTTP {{HTTPHeader("Permissions-Policy")}} header `local-network-access` directive controls whether the current document is allowed to make network requests to local and loopback addresses. This policy directive is an alias for the newer {{httpheader('Permissions-Policy/local-network','local-network')}} and {{httpheader('Permissions-Policy/loopback-network','loopback-network')}} directives.
The HTTP {{HTTPHeader("Permissions-Policy")}} header `local-network-access` directive controls whether the current document is allowed to make network requests to local and loopback addresses. This policy directive is an alias for the newer {{httpheader('Permissions-Policy/local-network','local-network')}} and {{httpheader('Permissions-Policy/loopback-network','loopback-network')}} directives. It is only supported in Chromium browsers.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Again, see above comments.


The HTTP {{HTTPHeader("Permissions-Policy")}} header `local-network-access` directive controls whether the current document is allowed to make network requests to local and loopback addresses. This policy directive is an alias for the newer {{httpheader('Permissions-Policy/local-network','local-network')}} and {{httpheader('Permissions-Policy/loopback-network','loopback-network')}} directives.

- A local address is only accessible on the local network: Its target will differ on different networks. For example, `http://192.168.0.1`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
- A local address is only accessible on the local network: Its target will differ on different networks. For example, `http://192.168.0.1`.
- A local address is only accessible on the local network: Its target will differ on different networks. For example, `192.168.0.1`.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

updated

- `local`
- : The request URL is a local address, which is only accessible on the local network: Its target will differ on different networks. For example, `http://192.168.0.1`.
- `loopback`
- : The request URL is a loopback address, which is only accessible on the local device: Its target will differ on every device. For example, `127.0.0.1`, which is generally known as `localhost`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
- : The request URL is a loopback address, which is only accessible on the local device: Its target will differ on every device. For example, `127.0.0.1`, which is generally known as `localhost`.
- : The request URL is a loopback address, which is only accessible on the local device: Its target will differ on every device. For example, `http://127.0.0.1`, which is generally known as `localhost`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

In this context we are talking about URLs explicitly, so let's make all of these be fully specified URLs for consistency?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In light of your previous comments, I ended up changing these to talk about addresses rather than URLs (and on the targetAddressSpace property page). Have a look at the updated pages after my next commit and see what you think. I can happily change them again, if you think we'd be better off talking specifically about URLs here.

- `local`
- : The request URL is a local address, which is only accessible on the local network: iIts target will differ on different networks. For example, `http://192.168.0.1`.
- `loopback`
- : The request URL is a loopback address, which is only accessible on the local device: Its target will differ on every device. For example, `127.0.0.1`, which is generally known as `localhost`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
- : The request URL is a loopback address, which is only accessible on the local device: Its target will differ on every device. For example, `127.0.0.1`, which is generally known as `localhost`.
- : The request URL is a loopback address, which is only accessible on the local device: Its target will differ on every device. For example, `http://127.0.0.1`, which is generally known as `localhost`.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

See above comment

- A website accessing a local device to provide configuration details during a setup procedure.
- A website connecting to a local site (such as an intranet) to provide authentication information, or as part of test environment.

Allowing local network access comes with risks — attackers can use such requests to initiate [cross-site request forgery (CSRF)](/en-US/docs/Web/Security/Attacks/CSRF) attacks against local network devices such as routers and printers, and fingerprint the user's local network. Local network access mitigates these risks, controlling local network access via a set of permission prompts and {{httpheader("Permissions-Policy")}} directives.
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.

I'd love a bit more of an unpacking of this. How does the CSRF attack work, and how are existing CSRF defenses not adequate to protect us?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@christhompson, what would you advise adding as an answer to this? I agree that a bit more info would be good, although we don't want it to take over the article.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Content:HTML Hypertext Markup Language docs Content:HTTP HTTP docs Content:Security Security docs Content:WebAPI Web API docs size/m [PR only] 51-500 LoC changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants