How do clients smuggle a bearer token through Sec-WebSocket-Protocol on a WebSocket upgrade, and what must the server echo?
answer
- one of two inputs a page controls
- fields are logged less than targets
- a negotiation field carrying a credential
- select exactly one value to echo
- never echo the token back
basics
~20 sThe client offers two values — the real subprotocol name and a second value carrying the token — because the page can control that list. The server must select exactly one to echo, and it must be the subprotocol name, never the token.
solid answer
~40 sA page controls two things on the upgrade: the URL and the list of subprotocol names, which the browser sends as `Sec-WebSocket-Protocol`. So teams put the credential in the second slot — `cabinet.v1, bearer.<token>` — getting the token out of the request target and into a request field, where loggers are far less likely to record it. The cost is that this field is a negotiation mechanism being used as a credential channel. The server must pull the token out, authenticate it, and then answer with **exactly one** selected value, which must be the genuine subprotocol name: echoing the token would write the credential into the response and hand back something that is not a subprotocol the client can speak.
code
http · 13 linesGET /cabinet/socket HTTP/1.1
Host: console.example.org
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Sec-WebSocket-Protocol: cabinet.v1, bearer.kQ7mS1xbN0
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: cabinet.v1go deeper
Know that the client offers subprotocol names on the upgrade and the server selects at most one of them, and that a page can choose what goes in that list.
Explain why the list is attractive as a credential channel — request fields are rarely logged, request targets always are — and what the server must echo back.
Judge it as a leak-surface improvement with no effect on credential lifetime, and say when a ticket or a plain request field is the better answer.
Weigh overloading a standard negotiation field across a client fleet against the endpoint split that would let service clients use an ordinary request field.
## Why anyone does this A browser page has two inputs to the upgrade: the URL and the subprotocol list. The URL is the request target, and request targets are logged everywhere. The subprotocol list becomes a request field, and request fields are logged far less often — most default access-log formats record the method, the target, the status and the size, and nothing else. So the trick is to offer two values where one is real: ```http Sec-WebSocket-Protocol: cabinet.v1, bearer.kQ7mS1xbN0 ``` The first is the application subprotocol the connection will actually speak. The second is not a subprotocol at all — it is a credential wearing a subprotocol's clothes. The server splits the list, recognises the prefixed value as a credential, authenticates it, and proceeds. ## What the server owes in reply Subprotocol negotiation is a selection: the client offers, the server picks **at most one** and names it in its `Sec-WebSocket-Protocol` response field, and a server must not name a value the client did not offer. Two consequences fall out of that, and they are the specific cost of this abuse: - **The server must echo exactly one value, and it must be the real subprotocol name.** Returning both is not a selection. Returning the token is worse: it writes the credential into the response, where a response-logging intermediary or a stored error page can capture it, and it tells the client to speak a subprotocol that does not exist. - **The server must still complete negotiation correctly for the real value.** The client offered `cabinet.v1` because it intends to speak it; the credential value must be stripped before the selection logic runs, or the server ends up choosing between a protocol and a password. The negotiation rule itself — what a selected name means, how extensions differ, what a client does when nothing is selected — belongs to the leaf that owns subprotocols. What belongs here is that **using the field as a credential channel puts an obligation on the response that an ordinary negotiation does not have.** ## What it buys and what it does not | | Token in the query string | Token as a subprotocol value | |---|---|---| | Recorded in default access logs | yes, as part of the request target | rarely: request fields are usually not logged | | In browser history | yes | no | | Travels in a copied URL | yes | no | | Abuses a mechanism | no | yes: a negotiation field carries a credential | | Server-side complexity | parse a query parameter | split a list, strip a value, select correctly | | Expires any faster | no | no | It is a genuine improvement on the leak surface and **no improvement at all on lifetime**. A long-lived token smuggled through the subprotocol list is still a long-lived token; if it does end up in a field-logging intermediary or a debug capture, it is just as useful to whoever finds it. Pairing the technique with a short-lived, single-use value gets you both properties. ## Where it is the wrong answer - **On a non-browser client**, always. A service can set `Authorization`; there is no reason to overload a negotiation field. - **When the value is long-lived.** The technique moves where a credential is written down, not how long it is worth having. - **When you do not control the server.** This only works if the server is written to expect it, because the extra value is meaningless to anything else and a strict implementation may simply select nothing. ## What an interviewer is listening for That you can explain *why* the field is attractive — it is one of exactly two things a page controls, and it is not the request target — and that you know the echo obligation. Candidates who have only read about the trick describe the request and stop; the response half is the part that has a rule attached to it.
- Does this technique make the credential any safer if it is stolen?No. It changes where the value is written down, not what the value is worth. A long-lived token recovered from a field-logging intermediary or a debug capture authorizes everything it normally authorizes. The leak surface and the credential's lifetime are independent properties, and the technique only addresses the first — pair it with a short-lived single-use value to get both.
- What happens if the server echoes both offered values?It has not made a selection, which is not what the response field means — the server names at most one. Beyond being wrong, echoing the credential value writes it into the response, where a response-logging intermediary or a captured error page can record it, and it tells the client to speak a subprotocol nothing implements.
saying these in an interview costs you the question
- Thinks the extra value is a real subprotocol the server implements
- Echoes every offered value back in the response field
- Echoes the credential value as the selected subprotocol
- Believes the technique shortens the credential's useful life
- Uses it from a service client that could set a request field instead