fix(server): fail closed when SOCKET_AUTH_TOKEN is unset (addresses #573 section C)#671
Open
Anexus5919 wants to merge 1 commit into
Open
fix(server): fail closed when SOCKET_AUTH_TOKEN is unset (addresses #573 section C)#671Anexus5919 wants to merge 1 commit into
Anexus5919 wants to merge 1 commit into
Conversation
|
@Anexus5919 is attempting to deploy a commit to the somiljain2024-4175's projects Team on Vercel. A member of the Team first needs to authorize it. |
Contributor
Author
|
@Somil450 Opened this pr to address section C (no auth by default) of this issue. It makes Kindly have a review on this pr. Thanks! |
Contributor
Author
|
@Somil450 Please have a review this pr. Thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📌 Related Issue
Addresses section C of #573 (the "No auth by default" item). This is intentionally not a "Fixes" link, because #573 also covers payload-limit hardening (sections A, B, D) handled separately by PR #574, so #573 should stay open. Also closes the live-path gap behind #449, whose recommended production guard only ever existed in the now-dead
server/src/app.jsand was never ported to the livecreateServer.js.📝 Description
Makes the Socket.IO server fail closed when
SOCKET_AUTH_TOKENis not configured, instead of silently accepting every unauthenticated connection.🔹 What has been changed?
server/src/app/createServer.js: the auth middleware is now always registered. WhenSOCKET_AUTH_TOKENis unset:NODE_ENVis explicitlydevelopmentortest(the intentional local-dev affordance from PR fix: harden Socket.IO backend (CORS allow-list, auth gate, rate limit, frame validation) #278 / feat: add socket auth, rate limiting, and CORS hardening #488),NODE_ENVunset, connections are rejected withError("Server misconfiguration: SOCKET_AUTH_TOKEN is not set"),config/socket.js)."Authentication failed: invalid or missing token").NODE_ENVis normalized withtrim().toLowerCase()so"Production"/" production "are handled correctly.server/package.json:devnow runs withNODE_ENV=developmentandstartwithNODE_ENV=production(viacross-env, added as a devDependency), so the local-dev affordance keeps working out of the box and production is explicit.server/tests/integration/auth.test.js: now covers all five states (token set + missing token -> reject, token set + valid -> accept, unset + dev -> accept, unset + production -> reject, unset + no NODE_ENV -> reject), withNODE_ENV/SOCKET_AUTH_TOKENrestored inafterEachand a fast-fail guard so a regression to "accept" fails immediately instead of timing out.server/tests/integration/socket.test.js: pinsNODE_ENVso the token-less frame-flow test is deterministic regardless of the ambient environment.🔹 Why are these changes needed?
SOCKET_AUTH_TOKENdefaults tonull(config/constants.js), and the previousif (SOCKET_AUTH_TOKEN) { io.use(...) }registered no auth middleware at all when it was unset, so any client could connect to the live server with no log and no rejection. The production-rejection guard #449 recommended was written intoapp.js, which is dead code (the live entry isindex.js -> createServer.js), so it never ran.🔹 Why fail closed (reject unless explicitly dev/test) rather than only on
NODE_ENV === "production"?An earlier draft rejected only when
NODE_ENV === "production", but an adversarial review showed that fails open in a common case: a production host that never setsNODE_ENVwould still accept unauthenticated connections (and the log would even claim "non-production"). For an auth gate, the secure default is to reject whenever the environment is not unambiguously local development. Thedev/startscripts setNODE_ENVso normal workflows are unaffected. This is slightly stricter than the warn-only precedent used for the CORS origin inconfig/socket.js, which is deliberate: an auth bypass is a higher-severity hole than a browser-enforced CORS warning.🛠️ Type of Change
🧪 Testing
✅ Tests Performed
cd server && npm test-> 13 files, 42 tests passed (40 pre-existing + 2 new auth cases).NODE_ENV=productionforced -> 42 passed, confirming the suite is robust to the ambient environment and the production-reject path works.🌐 Browsers Tested
Not applicable (backend change).
📷 Screenshots / Demo (if applicable)
Not applicable (backend logic + tests).
📋 Checklist
💬 Additional Notes
Branched from latest
upstream/main(834824e). Scope is limited to the auth-by-default item; the memory/disk payload-limit vectors of #573 (A/B/D) are out of scope here and tracked by PR #574.Behavior change to be aware of: a production deployment that runs without
SOCKET_AUTH_TOKENwill now reject socket connections (fail closed) instead of accepting them. That is the intended secure outcome; setSOCKET_AUTH_TOKENto enable authenticated connections. Local development is unaffected becausenpm run devsetsNODE_ENV=development.