RoastMyOpsec

Safety

Private Network Access vs CORS for Browser APIs

April 7, 2025

Private Network Access vs CORS for browser APIs is two different gates. CORS (Access-Control-Allow-Origin) decides whether a web page may read a cross-origin HTTP response. Private Network Access (PNA, evolving as Local Network Access in Chromium) is an extra browser rule: a page on the public internet should not casually fetch RFC1918, localhost, or other less-public addresses without a dedicated preflight and a target that opts in. Wildcard CORS on an internal API is still a miss; PNA is not a substitute for locking that API off the public origin. RoastMyOpsec refuses to scan localhost and private IPs. It does not send PNA preflights, does not map your LAN, and does not score missing PNA headers as an F.

The practical difference

CORS is origin-to-origin on the web. PNA is public-to-private (and similar) address space. A marketing page that fetch()es http://192.168.1.1/ to 'detect the router' is the anti-pattern these rules exist to shrink. WebSockets and JSONP are other costumes — see those guides. Consent-based scanning of URLs you own is a different product than a page probing the visitor's LAN.

Internal admin APIs belong on VPN, mTLS, or a hostname that is not reachable from random laptops on café Wi-Fi. Do not rely on 'nobody knows the IP.'

How to choose a policy

Public marketing site: do not fetch private IPs or localhost from page JavaScript. Device setup flows that must talk to a local appliance: follow current browser PNA/Local Network Access guidance, user-visible permission, and a target that only opts in for that product. CORS allowlists stay named origins. RoastMyOpsec customers paste public HTTPS URLs — not 10.0.0.0/8.

ControlWhat it gatesPublic site defaultTakeaway
CORS ACAOCross-origin read of HTTPNamed origins, not *See CORS wildcard vs allowlist
Private Network AccessPublic page → private addressDo not fetch LAN/localhostNot a roast header check
Firewall / VPNWho can reach the APIInternal APIs stay internalThe real lock
URL roast scopeConsented public HTTPSNo private IPsSee consent-based scan

When PNA still wins

PNA wins as a browser brake when a XSS gadget on a public origin tries to talk to the visitor's LAN. CORS still wins for ordinary API reads. Neither replaces keeping admin off the public internet. Pair with consent-based scan vs unsolicited probing.

What the roast can prove

ACAO on a bounded untrusted Origin can surface for public URLs. PNA headers are not scored. Private targets are rejected before a fetch. Pair with CORS credentials vs wildcard if the internal API also reflects Origin.

Common mistakes

The first mistake is a public SPA that probes localhost 'to see if the desktop agent is running' without a current PNA design.

The second mistake is Access-Control-Allow-Origin * on an RFC1918 API.

The third mistake is treating a roast refusal of a private IP as a scanner bug.

Free audit the URL you own

RoastMyOpsec is a defensive public-surface roast: headers, cookies, sensitive paths, and more — no exploit payloads. Start with the free audit, then open the vault if the blurred findings look expensive.

Free audit now

FAQ

Does CORS replace Private Network Access?
No. CORS is cross-origin reads. PNA is an extra gate for public pages reaching private addresses.
Will RoastMyOpsec scan my printer or localhost?
No. Localhost and private IPs are blocked. Paste a public origin you own.
Does RoastMyOpsec send PNA preflights?
No. It does not map LANs or score PNA headers.

Sources

Related guides