Skip to content

Sprint 1 security hardening: secrets, SSRF, SQLi, IDOR, CORS, deps#101

Merged
keysersoft merged 1 commit into
mainfrom
keysersoft/full-review
May 2, 2026
Merged

Sprint 1 security hardening: secrets, SSRF, SQLi, IDOR, CORS, deps#101
keysersoft merged 1 commit into
mainfrom
keysersoft/full-review

Conversation

@keysersoft

Copy link
Copy Markdown
Contributor

Summary

First batch of security blockers from the full project review. All seven Sprint 1 tasks completed.

  • Secrets: removed hardcoded JWT_SECRET / ENCRYPTION_KEY fallbacks; new secrets.util.ts validates required secrets at boot (length ≥ 32, rejects known placeholders) — app refuses to start otherwise.
  • SSRF: new ssrf.util.ts with DNS-aware host check (resolves the hostname before allowing the request, so DNS rebinding to private IPs is also blocked). Covers loopback / 169.254 metadata / RFC1918 / link-local / IPv4-mapped IPv6. Integrated into REST, GraphQL, SOAP, MCP-client, OAuth2 token, mcp-oauth, and the OpenAPI / Postman / GraphQL spec fetchers. Auto-disabled in jest.
  • SQL injection: DatabaseEngine now compiles templates to driver-specific prepared statements ($1 pg, ? mysql/sqlite, @p0 mssql, :b0 oracle); values are bound, never inlined. The legacy ${query} raw-mode is kept for admin SELECT-only introspection.
  • Template injection: REST bodyTemplate rejects __proto__ / constructor / prototype param keys, escapes string values JSON-safely, and re-validates the parsed result.
  • IDOR: tools update/delete are pinned to connectorId via updateMany/deleteMany; roles service has new findByIdForOrg, update, delete, setToolAccess, assignRoleToUser overloads that take organizationId and refuse cross-tenant operations; users admin endpoints (role change, delete, invitation revoke) confined to the requesting org.
  • HTTP: Helmet middleware, HSTS in prod, CORS rejects '*' + credentials in production, per-endpoint throttle (auth-strict 5/min on login / register / password-reset, auth 10/min on resend-verification).
  • Dependencies: npm audit fix brings vulnerabilities from 43 (1 critical, 22 high, 20 moderate) down to 11 (1 high, 10 moderate, all transitive dev tooling). Dependabot config added.

Test plan

  • tsc --noEmit -p packages/backend/tsconfig.json clean
  • nest build produces dist
  • npm test baseline 5 failures (pre-existing, unrelated to this PR) — same 5 after; 7 new tests added pass
  • manual smoke: start backend with missing secrets → fails fast
  • manual smoke: connector pointing at http://169.254.169.254/... → blocked by SSRF guard
  • manual smoke: tool with template WHERE name = \$name and param "x'; DROP TABLE users; --" → bound as parameter, no SQL executed

- Remove hardcoded JWT_SECRET / ENCRYPTION_KEY fallbacks; validate at boot
- Add SSRF guard with DNS resolution + RFC1918/loopback/cloud-metadata blocklist
  and integrate it across REST, GraphQL, SOAP, MCP-client, OAuth2 token,
  mcp-oauth, and OpenAPI/Postman/GraphQL parsers
- Refactor DatabaseEngine to use prepared statements (pg/mysql/mssql/oracle/sqlite)
- Fix prototype pollution / template injection in REST bodyTemplate
- Enforce per-organization scoping on tools, roles, users, invitations
- Helmet middleware, harden CORS (reject '*' with credentials in prod),
  per-endpoint rate limiting on login / register / password-reset
- Update vulnerable deps (path-to-regexp, @nestjs/core, xmldom, axios,
  serialize-javascript, nodemailer); add Dependabot config
@keysersoft
keysersoft merged commit 61ce977 into main May 2, 2026
@keysersoft keysersoft mentioned this pull request May 2, 2026
@keysersoft
keysersoft deleted the keysersoft/full-review branch May 12, 2026 08:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant