Two pieces of housekeeping that had gone quiet.
**A code-scanning alert nobody had looked at.** CodeQL flagged js/log-injection
in the preflight handler: a request value interpolated straight into a log line.
Log entries are newline-delimited, so a value containing a line break forges
additional entries — and an audit trail its own subject can write into is worse
than none, because it is believed.
The interesting part is that the risk had already been recognised. Two sites in
the clients routes strip carriage returns inline, ad hoc, and the third was
simply missed. That is what a shared helper is for, so there is now a `logSafe`
utility with tests, used at all three. It replaces control characters with a
visible marker rather than stripping them, so a tampered value reads as tampered
instead of being quietly tidied, and truncates absurd input so one field cannot
flood the log.
**Twelve Dependabot pull requests, the oldest six weeks old.** Nine had passing
checks, but those runs were from July against a main that has moved a long way,
so rather than merging stale branches serially the eight safe ones are applied
here as one change and verified together: bullmq, pg, helmet, @types/supertest,
tailwind-merge, vite, actions/setup-node and github/codeql-action.
Deliberately excluded, and left open:
* bcryptjs 2.4.3 to 3.0.3 (#79) — a major on the password-hashing path.
Dependabot groups it with routine bumps; it is not one, and it deserves
its own verification rather than riding along in a batch.
* typescript 5.9 to 7.0 (#81), tailwindcss 3.4 to 4.3 (#76) and
eslint-plugin-react-hooks (#78) — all three already fail their own checks.
Verified beyond the gates: the application was rebuilt and exercised on the new
dependencies — authentication, the BullMQ-backed poller, Postgres reads and
helmet's headers all behave.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Address the open CodeQL code-scanning alerts:
- guestWifi voucher codes now use rejection sampling so the character
distribution is uniform (fixes js/biased-cryptographic-random).
- Scheduled-report recipient validation replaced the backtracking email regex
with a linear split-based check (fixes js/polynomial-redos).
- Add .github/codeql/codeql-config.yml excluding js/missing-rate-limiting:
rate limiting is applied globally via app.use('/api', rateLimitRedis) plus
per-route limiters, which CodeQL can't attribute to individual handlers, so
that rule fired ~38 false positives.
Remaining alerts are dismissed as accepted/false-positive (RouterOS MD5 API
login and self-signed cert acceptance are protocol-mandated; log sites already
strip CRLF).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- SECURITY.md with vulnerability disclosure policy and self-hosting guidance
- Dependabot config for weekly dependency updates (npm, Docker, Actions)
- ESLint v9 flat config for frontend and backend, with eslint-plugin-security
- GitHub Actions CI: lint, typecheck, build, and npm audit on every push/PR
- CodeQL workflow for automated security scanning (runs on push and weekly)