Websocket security
Skill ShieldNet-360/secure-vibe/dist/copilot-skills/.github/skills/websocket-security
SecureVibe — prevention-first security for AI-written code. Signed SKILL.md knowledge that makes AI coding assistants write secure code at generation time, plus a deterministic CI gate. Offline · keyless · Ed25519-signed. By ShieldNet360.
npx -y skills add ShieldNet-360/secure-vibe --skill websocket-securityAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Secure WebSocket endpoints: Origin validation, auth on handshake, message size/rate limits, wss-only, reconnection backoff — Applies to: when generating a WebSocket / Socket.IO / SignalR server; when wiring real-time messaging, presence, or collaborative editing; when reviewing /ws or wss:// endpoint exposure
SKILL.md
4.7 KB, 985 tokens by cl100k_base, as published. Nobody here has run it
WebSocket Security
Secure WebSocket endpoints: Origin validation, auth on handshake, message size/rate limits, wss-only, reconnection backoff
ALWAYS
- Validate the
Originheader on the WebSocket upgrade handshake against an allowlist. CORS does not apply to WebSockets — the browser will happily upgrade cross-origin and let JavaScript onattacker.comopenwss://api.example.com/wswith the user's cookies (Cross-Site WebSocket Hijacking). - Require authentication on the handshake itself, not as the first message after connect. Either: 1. Cookie-based auth on the HTTP upgrade (and CSRF-protect by verifying Origin), or 2. A short-lived signed token (5–10 minute lifetime) in the
Sec-WebSocket-Protocolsubprotocol header, or 3. A signed query parameter token. Never trust asubscribe/authmessage after the upgrade — by that point the connection has already been opened with the authenticated cookie context. - Use
wss://only in production. Plainws://over the open internet exposes session tokens, message contents, and CSRF primitives to any on-path observer. - Enforce max message size at the server (typical: 32 KiB for chat, 256 KiB for collaborative editing, much higher only when the use case demands it and the auth bar is high). Without a limit, a single open socket can OOM the server.
- Enforce a message rate limit per connection (e.g. 60 messages/minute) and a connection rate limit per source IP / per authenticated user. Real-time abuse (chat spam, presence ping flood) is a frequent DoS source.
- Implement ping / pong heartbeats (every 20–30 s) and close the connection on missed pong. Half-open TCP sockets accumulate behind load balancers otherwise.
- On the client side, use bounded exponential backoff for reconnection (e.g. base 1 s, factor 2, max 60 s, jitter ±20%). A naïve
setTimeout(connect, 0)reconnect loop melts the server during outages. - Treat each WebSocket message as a separate request for the purposes of input validation and authorization. The user's permissions can change after the socket is open (logout, role change, account lock) — re-check on each privileged action.
- Object-level-authorize the subject / resource id carried in each message, not just the action type. A frame like
{"action":"write","subjectId":"X"}must be checked so the connection's handshake-authenticated principal may actually act onX. An authenticated socket must not be able to assert an arbitrary subject id per frame — that is per-frame BOLA, and the forged id reaches any consumer downstream of the socket (queue / topic / fan-out) that trusts it.
NEVER
- Skip Origin validation because "it's a WebSocket, CORS doesn't apply." That's exactly why you have to do it yourself. The documented attack is Cross-Site WebSocket Hijacking, demonstrated publicly in 2013 and still common in 2024 bug-bounty reports.
- Use a session cookie as a long-lived WebSocket token. If the WS connection is supposed to survive multiple tabs / pages, issue a refreshable short-lived JWT in the subprotocol; don't rely on the cookie sticking around forever.
- Allow arbitrary
subprotocolsfrom the client to influence server-side routing without an allowlist. Subprotocol negotiation is attacker-controlled. - Run WebSocket handlers in the same process / thread pool as HTTP request handlers without sizing limits — a slow-loris-style WebSocket can starve all HTTP work.
- Expose internal cluster topology in WebSocket messages (e.g.
{"server_id": "pod-prod-42"}). Internal IDs are reconnaissance material on a chatty real-time channel.
KNOWN FALSE POSITIVES
- Public chat / presence endpoints that are intentionally open to any origin must still enforce per-connection rate limits and a per-source-IP cap; they may legitimately permit
Origin: nullfor desktop / mobile clients. - Mobile / desktop native clients send no
Originheader. Decide upfront whether to allow them (and apply a different auth mode like device-cert + bearer token) or to reject them outright. - Service-to-service WebSockets (e.g. Kafka WebSocket bridge, Apache Pulsar) inside a private VPC may legitimately use
ws://with mTLS handled at the network layer.
What ships with it: 1 file
1.1 KB alongside SKILL.md
- metadata.json1.1 KB