-
Notifications
You must be signed in to change notification settings - Fork 20
Description
Summary
The LNA permission prompt is sound for the common case: unauthenticated HTTP requests to raw IPs where the browser cannot verify the target's identity or intent.
However, when a local network target serves a publicly-trusted TLS certificate and explicitly opts in via a CORS preflight, every security property the permission prompt provides is already established cryptographically — and more reliably than a user clicking "Allow." I propose exempting these requests from the prompt.
Use Case
I built ProxyBox Zero, a hardware device that acts as an HTTPS reverse proxy between cloud web applications and local network peripherals (printers, scales, barcode scanners). Our customers are small manufacturers, warehouses, and agricultural operations — no IT departments, no enterprise-managed devices.
How it works:
- ProxyBox gets a local IP (e.g.,
192.168.1.50) - DNS points
{device-id}.pbxz.io→192.168.1.50via Cloudflare - Caddy uses the DNS-01 ACME challenge to obtain a publicly-trusted, CT-logged Let's Encrypt certificate
- Cloud ERPs make
fetch()calls to the device over browser-trusted HTTPS
The firmware is fully updatable — we can implement any preflight or handshake protocol the spec requires. Enterprise policies (LocalNetworkAccessAllowedForUrls) are not viable for our market; our users don't know what Chrome policies are.
The Core Argument
The LNA explainer states:
"Even if the local device has opted in to connections from a top level site, we believe there is value in user awareness and control over this exchange."
This was written about the original PNA preflight, where "opted in" meant an unauthenticated HTTP server at some IP returned a header — a weak signal. User awareness meaningfully adds security there.
But when the target serves a publicly-trusted certificate with CT logging, responds to a preflight with Access-Control-Allow-Private-Network: true, and communicates over HTTPS end-to-end, the prompt is confirming what's already been established cryptographically.
What attack does the permission prompt prevent that the TLS handshake + preflight does not?
| Threat | How TLS + preflight addresses it |
|---|---|
| CSRF against local devices | Target explicitly opts in via preflight; attacker cannot forge opt-in without controlling the device |
| Drive-by exploitation of vulnerable services | Vulnerable devices don't serve publicly-trusted certs or respond to preflights; they remain protected by the prompt |
| Network fingerprinting / scanning | Attacker must guess a valid hostname with a matching publicly-trusted cert on a local IP — see timing discussion below |
| User unawareness | The user physically installed the device and configured their ERP to use it |
Why Previous Preflight Concerns Don't Apply
"Legacy devices can't implement preflights"
This proposal doesn't change anything for legacy devices. They continue through the permission prompt. This is a strictly additive path for devices that can meet the security bar.
"Timing attacks could determine valid IP addresses"
The original PNA preflight was sent to arbitrary IPs over HTTP, enabling topology discovery via timing (crbug.com/40051437, WICG/private-network-access#41). Under this proposal, the target must complete a TLS handshake with a publicly-trusted certificate matching the requested hostname. An attacker scanning local IPs sees:
- No TLS listener → connection refused (no new information vs. any closed port)
- Wrong/self-signed cert → handshake fails (no preflight sent)
- Valid cert, wrong hostname → verification fails (no preflight sent)
Reaching the preflight stage requires knowing a valid hostname that resolves locally and is served by a device with a matching public cert. At that point, the attacker already knows more than preflight timing would reveal.
"User awareness has value even with device opt-in"
The spec authors compare LNA to iOS/Android local network permissions. But those OS-level permissions are per-application, persistent, and one-time — they aren't reset by OS updates or profile changes. The browser permission prompt's persistence is implementation-defined and in practice fragile (browser updates, profile resets, switching browsers all re-trigger it). A TLS+preflight exemption would actually be closer to the OS model: durable authorization established by a strong signal.
Proposal
Exempt local network requests from the permission prompt when all conditions are met:
- HTTPS end-to-end (no mixed content)
- Target serves a certificate from a publicly-trusted CA (in the browser's root store)
- Target responds to CORS preflight with
Access-Control-Allow-Private-Network: true - Standard CORS requirements satisfied
If any condition isn't met, fall back to the current permission prompt.
if (isLocalNetworkRequest(request)) {
if (connection.isHTTPS &&
connection.certificate.isPubliclyTrusted &&
preflightResponse.has("Access-Control-Allow-Private-Network: true") &&
corsRequirementsMet(preflightResponse)) {
return null; // Allow — security properties already satisfied
} else {
// Existing permission prompt flow
}
}
This changes nothing for unauthenticated requests, legacy devices, or the spec's core security model. Users can still block local network access via Permissions Policy and browser settings.
Questions for Discussion
- Are there attack scenarios where a valid publicly-trusted cert + preflight opt-in should still be blocked?
- Should the browser surface exempted connections in a settings panel (e.g., "Connected local devices") for transparency without friction?
- Would
Private-Network-Access-ID/Private-Network-Access-Nameheaders be useful for that UI?
Related Issues & Specs
- WICG/private-network-access — Original preflight-based spec (superseded by LNA)
- WICG/private-network-access#41 — Timing attack concerns with preflights
- WICG/private-network-access#117 — Preflight origin trial feedback
- LNA Explainer — Rationale for permission-based approach (see "Considered Alternatives")
- Chrome Intent to Ship — Shipping details
- LNA Spec §1.2 — "This spec does not attempt to make it easier to use HTTPS connections on local network devices" (we solved this independently)