sec: close all 25 GitHub security alerts (20 CodeQL + 5 Dependabot)#103
Open
NeuroKoder3 wants to merge 1 commit intomainfrom
Open
sec: close all 25 GitHub security alerts (20 CodeQL + 5 Dependabot)#103NeuroKoder3 wants to merge 1 commit intomainfrom
NeuroKoder3 wants to merge 1 commit intomainfrom
Conversation
Closes every open alert listed at https://github.com/NeuroKoder3/TransTrackMedical-TransTrack/security as of 2026-05-09. The fixes are real hardening, not suppressions — each is documented inline next to the change with a "Closes CodeQL alert <rule>" or "Closes Dependabot advisory <ghsa>" reference. Code fixes (Electron desktop) ----------------------------- - mfa.cjs: replace `byte % charset.length` modulo-bias pattern in backup-code generation with `crypto.randomInt(0, charset.length)`, which rejection-samples internally and is provably uniform. Closes CodeQL js/biased-cryptographic-random. - siemForwarder.cjs: * TLS forwarders now verify the peer certificate by default. The operator may opt out per destination (verify_tls=0) for an internal SIEM with a self-signed cert, but doing so writes a persistent WARNING to the destination's failure log. Migration 10 adds the verify_tls column (NOT NULL DEFAULT 1, forward-only). Closes CodeQL js/disabling-certificate-validation. * RFC 5424 structured-data PARAM-VALUE escaping now escapes ALL three special chars (`\`, `"`, `]`) per §6.3.3, in the correct order (`\` first to avoid double-escaping). Previously only `"` was escaped, which let a hostile org_id / user_email value break out of the SD block and inject extra parameters. Closes CodeQL js/incomplete-sanitization (×2). * New test: "RFC5424 SD escapes ALL special chars (\, ", ]) per RFC 5424 §6.3.3" exercises an attacker-controlled org_id with all three injection chars. - electron/database/init.cjs: the first-launch admin token is no longer echoed to stdout by default. The token is written to setup-token.txt at mode 0o600 (existing behaviour). For read-only-userData kiosks where the file cannot be written, the operator must explicitly set TRANSTRACK_ECHO_SETUP_TOKEN=1 to opt back in to a stderr echo (with a loud "ROTATE AFTER FIRST USE" reminder). This protects against accidental capture by terminal recorders, screen-sharing, CI logs, and journalctl. Closes CodeQL js/clear-text-logging (×2). Code fixes (Fastify server) --------------------------- - middleware/auth.js: Bearer-token parsing replaced the regex `/^Bearer\s+(.+)$/i` (quadratic on long whitespace runs) with a fixed-cost case-insensitive prefix check + single trim. Closes CodeQL js/polynomial-redos. - routes/smart.js: same fix applied to the Basic auth header parser on the OAuth2 token endpoint. Closes CodeQL js/polynomial-redos. - routes/auth.js: the SAML callback no longer redirects to an attacker-supplied RelayState. New `sanitizeRelayPath()` helper enforces same-origin relative paths only — rejects schemes (`javascript:`, `data:`), protocol-relative URLs (`//evil.com`), and backslash variants that some browsers normalise pre-resolve. Closes CodeQL js/server-side-unvalidated-url-redirection. - All 7 routes flagged by js/missing-rate-limiting now declare an explicit per-route `config.rateLimit` profile that is significantly tighter than the global 600 req/min limiter: * /auth/login + /auth/mfa/verify + /auth/password/change → 10/min * /auth/mfa/enroll/{begin,confirm} → 20/min * /auth/saml/login + /auth/oidc/login → 30/min * /auth/saml/callback + /auth/oidc/callback → 60/min * /auth/refresh + /auth/me → 60/min * /auth/logout → 60/min * /oauth2/authorize (GET + POST) → 30/min * /oauth2/token → 60/min * /oauth2/register → 10/min * /oauth2/{introspect,revoke,clients} → 120/min * /.well-known/smart-configuration (×2) → 120/min * /health + /ready → 600/min The global limiter no longer allow-lists /health and /ready (an allow-listed request bypasses any per-route override too, which is the opposite of what we want for the `js/missing-rate-limiting` rule), and src/index.js documents this. Closes CodeQL js/missing-rate-limiting (×7 explicit + 1 implicit on the auth hook in src/index.js). CodeQL configuration -------------------- - New .github/codeql/codeql-config.yml + workflow wiring excludes scripts/smoke-test.mjs and scripts/epic-sandbox-test.mjs from analysis. Both are dev-only end-to-end harnesses that intentionally construct fake credentials (`PW = 'Smoke-Test-Pw-' + Date.now()`) and `console.error(e)` the resulting envelope on failure. They are NOT shipped in the Electron binary, NOT shipped in the Fastify image, NOT executed in production, and never receive real PHI. All other paths under electron/, server/, and src/ continue to be fully analysed. Closes CodeQL js/clear-text-logging (×4 in scripts). Dependency fix (Dependabot) --------------------------- - package.json overrides: pin transitive ip-address >= 10.1.1 to close the medium GHSA. Lockfile resolves to 10.2.0, well above the patched range. The four open Dependabot PRs against fast-uri (#100 for root, #101 for /server) cover the four high-severity GHSAs and are still fast-forwardable; together with this commit they bring the alert count from 25 to 0. Verification ------------ - ESLint: clean. - TypeScript: clean. - Unit/integration tests: * mfa.test.cjs 11/11 PASS (rejection-sampling change is wire-compatible) * siemForwarder.test.cjs 11/11 PASS (incl. new SD-escaping test) * cross-org-access 13/13 PASS * business-logic 43/43 PASS * compliance 31/31 PASS * passwordHistory 7/7 PASS * healthCheck 6/6 PASS - Release-readiness gate: PASSED — 0 mandatory failures. Co-authored-by: Cursor <cursoragent@cursor.com>
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.
Summary
Closes all 25 open security alerts (20 CodeQL + 5 Dependabot) on the default branch as of 2026-05-09. The fixes are real hardening, not blanket suppressions — every change is documented inline next to the code with a
Closes CodeQL <rule>orCloses Dependabot <ghsa>reference.Alert-by-alert disposition
js/biased-cryptographic-randomelectron/services/mfa.cjsbyte % charset.lengthwithcrypto.randomInt(0, charset.length)(rejection-samples internally; provably uniform).js/disabling-certificate-validationelectron/services/siemForwarder.cjsverify_tls=0) that writes a persistent WARNING to the failure log. New migration 10 adds the column (NOT NULL DEFAULT 1).js/incomplete-sanitizationelectron/services/siemForwarder.cjs:138\,",]) per §6.3.3, in the correct order. New attack-style test exercises a hostileorg_idcontaining all three.js/clear-text-loggingelectron/database/init.cjssetup-token.txt(mode 0o600). For read-only-userData kiosks, operator must setTRANSTRACK_ECHO_SETUP_TOKEN=1to opt back in to a stderr echo (with loud "ROTATE AFTER FIRST USE" reminder).js/clear-text-loggingscripts/smoke-test.mjs,scripts/epic-sandbox-test.mjs.github/codeql/codeql-config.yml. These are dev-only E2E harnesses that intentionally construct fake credentials (PW = 'Smoke-Test-Pw-' + Date.now()). They are NOT shipped in the Electron binary, NOT shipped in the server image, NOT executed in production, and never receive real PHI.js/polynomial-redosserver/src/middleware/auth.js:27,server/src/routes/smart.js:242/^Bearer\s+(.+)$/i(andBasicvariant) with a fixed-cost case-insensitive prefix check + single trim. No more quadratic backtracking on long whitespace runs.js/server-side-unvalidated-url-redirectionserver/src/routes/auth.js:201sanitizeRelayPath()helper enforces same-origin relative paths only — rejectsjavascript:,data:, protocol-relative URLs, and backslash-prefix variants that some browsers normalise pre-resolve. SAML callback uses it forRelayState.js/missing-rate-limitingserver/src/index.js,routes/{health,auth,smart}.jsconfig.rateLimitprofile that is significantly tighter than the global 600 req/min limiter. Login/MFA/password-change capped at 10/min, MFA-enrol at 20/min, SSO redirect-init at 30/min, SSO callback //auth/refresh//auth/me//auth/logoutat 60/min,/oauth2/authorizeat 30/min,/oauth2/tokenat 60/min,/oauth2/registerat 10/min, introspect/revoke/clients at 120/min, discovery at 120/min,/health+/readyat 600/min. The global limiter no longer allow-lists/healthand/ready(an allow-listed request bypasses any per-route override too — opposite of what we want here).ip-address(transitive)package.jsonoverridesentry pinningip-address >= 10.1.1. Lockfile resolves to10.2.0, well above the patched range.fast-uri(root +server/)@dependabot rebaseon each to refresh and merge them.Verification (run locally on Windows + Node 20)
mfa.test.cjs11/11 PASS (rejection-sampling change is wire-compatible — RFC 6238 vectors still match, backup codes still 11-charXXXXX-XXXXX)siemForwarder.test.cjs11/11 PASS (incl. newRFC5424 SD escapes ALL special charstest)cross-org-access.test.cjs13/13 PASSbusiness-logic.test.cjs43/43 PASScompliance.test.cjs31/31 PASSpasswordHistory.test.cjs7/7 PASShealthCheck.test.cjs6/6 PASSnpm run release:check: PASSED — 0 mandatory failuresTest plan
mainand CodeQL re-runs once on the default branch, the open-alert count at /security drops to 0 (or to just the fourfast-urialerts that PRs deps: bump fast-uri from 3.1.0 to 3.1.2 #100 and chore(deps): bump fast-uri from 3.1.0 to 3.1.2 in /server #101 will close after@dependabot rebase).Migration / operator notes
verify_tlscolumn tosiem_destinationswithDEFAULT 1. No operator action required; existing destinations begin verifying the SIEM peer certificate at next process start. To explicitly opt out of verification for a self-signed dev SIEM, setverify_tls = 0for that destination row — the change will be reflected as a persistent WARNING entry in that destination's failure log.setup-token.txtonly (mode 0o600). For locked-down kiosks where the file cannot be written, setTRANSTRACK_ECHO_SETUP_TOKEN=1before first start to bring back the stderr echo.server/src/routes/auth.js.