v147 · Security · WebSockets Demo
WebSockets Demo
Illustrates which WebSocket connections Chrome 147 blocks versus allows, and what the LNA preflight looks like for connections from public pages to local network servers.
Chrome 147 adds LNA checks to WebSocket connections. The preflight is an HTTP GET request (before the WebSocket upgrade) with
Access-Control-Request-Private-Network: true. The local server must respond with Access-Control-Allow-Private-Network: true.
try a WebSocket target
Classify a target URL and optionally invoke the WebSocket constructor to see the browser's readyState/error path from this page.
Choose a target, then classify or open a short WebSocket probe.
blocked vs allowed
Blocked (needs LNA opt-in)
- Public page →
ws://192.168.x.x:port - Public page →
ws://10.x.x.x:port - Public page →
ws://172.16-31.x.x:port - Public HTTPS page →
ws://localhost:port - Public page → any
.localmDNS host
Allowed (no opt-in needed)
- Local page → local WebSocket server
- localhost → localhost WebSocket
- Public page → public WebSocket server
- Local server responding with
Access-Control-Allow-Private-Network: true
connection type matrix
| Source context | WebSocket target | Chrome 147 result |
|---|---|---|
| https://public.example.com | ws://192.168.1.100:8080 | Preflight required → allowed if server opts in |
| https://public.example.com | ws://localhost:3000 | Preflight required → allowed if server opts in |
| https://public.example.com | wss://api.public.example.com | Allowed — both public |
| http://192.168.1.50 | ws://192.168.1.100:8080 | Allowed — both private |
| http://localhost:3000 | ws://localhost:8080 | Allowed — both localhost |
server fix
// Local WebSocket server — Node.js with 'ws' package
const { WebSocketServer } = require('ws');
const wss = new WebSocketServer({ port: 8080 });
// The server must handle the LNA preflight GET request
// before the WebSocket upgrade
const http = require('http');
const server = http.createServer((req, res) => {
if (req.headers['access-control-request-private-network']) {
res.writeHead(200, {
'Access-Control-Allow-Origin': req.headers.origin || '*',
'Access-Control-Allow-Private-Network': 'true',
});
res.end();
return;
}
res.writeHead(404);
res.end();
});
// Attach WebSocket server to the same HTTP server
const wssWithHttp = new WebSocketServer({ server });
server.listen(8080);
see also
implementation reference
Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗