<random_key><accept_response>GET /websocket HTTP/1.1
Host: localhost:8080
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://localhost:8080
Cookie: auth_token=8f3a91c2...Sec-WebSocket-Key is 16 random bytes, base64 encoded, new for every connectionOrigin and Cookie headers. We'll need both laterHTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=101 Switching Protocols is the last HTTP message on this connectionContent-LengthSec- are forbidden headers
fetch cannotfetch to fake a WebSocket handshakewss:// on a page served over https://
ws:// connections from https:// pages (mixed content)onmessage to a function that will be called whenever a message is receivedsend method to send a message to the serverauth_token cookie, hash it, look it up<script>
const socket = new WebSocket("ws://localhost:8080/websocket");
socket.onopen = () => socket.send(JSON.stringify(
{"messageType": "direct_message", "targetUser": "cse312", "text": "Sent by the attacker"}));
socket.onmessage = (message) => console.log("Stolen: " + message.data);
</script>Lax cookies are not sent on a cross-site handshakeLax or Strict
SameSite is not setStrict
http://localhost:5000 attacking http://localhost:8080 is same-site!Origin header with every WebSocket handshakeOrigin is a forbidden header. JavaScript can't change it
Origin is honestOrigin it wants
Origin and respond 403 Forbidden if it isn't one they expectPOST /api/websocket-ticket with its XSRF token/websocket?ticket=...fetch