demo · v138
Router-attack walkthrough
The CVE class this feature kills: a public web page silently posting to http://192.168.1.1/admin/dns to switch the user’s DNS to attacker.example. Walk through what pre-138 Chrome did and what 138 does instead.
Threat model. The user visits
attacker.example. Their router’s admin page is on the same LAN, accessible from a browser on the LAN, but typically not behind auth (or behind default admin/admin). Pre-138, the attacker page could fire a fetch() against the router’s IP. Same-origin policy doesn’t apply because the attacker doesn’t need to read the response — the side-effect (changing DNS) is the goal.
attacker.example
a.b.c.d (public)
malicious page running fetch("http://192.168.1.1/admin/dns?set=attacker.dns") on load
Chrome on the user’s LAN
10.0.0.34 (private)
in 138, requests from a public origin to a private destination are subject to LNA: must be preceded by a successful preflight + (where applicable) user permission.
Router admin
192.168.1.1 (loopback/private)
DNS = 1.1.1.1 (default)
what 138 actually does
- The browser classifies the destination IP (public → private → loopback) using the same ladder as the PNA spec.
- If the request crosses down the ladder — e.g. public-origin → private-IP — it issues an
OPTIONSpreflight withAccess-Control-Request-Local-Network: truefirst. - If the preflight fails (most routers don’t answer it) the request is blocked. No silent side-effect possible.
- If the destination is a secure private context, Chrome also prompts the user before allowing the request.