chore: root commit of OWSAP security testing/tightening
All checks were successful
Deploy / deploy (push) Successful in 1m42s
Security Tests / security-non-db (push) Successful in 20s
Security Tests / security-db (push) Successful in 22s

This commit is contained in:
2026-03-01 20:46:47 -06:00
parent 1645896e54
commit 079b8b9492
25 changed files with 1131 additions and 107 deletions

View File

@@ -0,0 +1,89 @@
# A02: Security Misconfiguration
Last updated: March 1, 2026
## Findings addressed
1. SMTP transport debug logging enabled in all environments.
2. Production CORS had a fail-open branch when configured origins were empty.
3. Missing explicit anti-framing headers at edge.
4. Docker compose exposed Postgres/API on all host interfaces.
## Fixes implemented
1. SMTP transport hardening in API:
- `requireTLS` now respects config (`SMTP_REQUIRE_TLS`).
- SMTP debug/logger are disabled in production (`!isProd` only).
2. CORS production behavior tightened:
- Removed fail-open branch for empty configured origins.
- Production now allows only explicitly configured origins.
3. Edge header hardening:
- Added `X-Frame-Options: DENY`.
- Added `Content-Security-Policy: frame-ancestors 'none'`.
4. Compose exposure reduction:
- Bound Postgres and API ports to localhost only.
## Files changed
1. `api/src/server.ts`
2. `Caddyfile.prod`
3. `Caddyfile.dev`
4. `deploy/nginx/skymoneybudget.com.conf`
5. `docker-compose.yml`
## Verification
### Automated security regression tests
Command (A01 regression):
```bash
cd api
npm test -- auth.routes.test.ts access-control.account-delete.test.ts
```
Verified output (provided from host run):
- Test Files: `2 passed (2)`
- Tests: `6 passed (6)`
- Start time: `16:39:35`
Command (A02 dedicated suite):
```bash
cd api
npx vitest --run -c vitest.security.config.ts
```
Verified output:
- Test Files: `1 passed (1)`
- Tests: `5 passed (5)`
- Suite: `tests/security-misconfiguration.test.ts`
Coverage in dedicated suite:
1. Production CORS allowlist enforcement (allowed origin accepted, denied origin does not receive allow headers).
2. SMTP production mailer options disable debug/logger.
3. Runtime CORS preflight headers validated for allowed origins (`allow-origin`, `allow-credentials`, `vary`).
4. Edge config files contain anti-framing headers (`X-Frame-Options`, `frame-ancestors` CSP).
5. `docker-compose.yml` binds Postgres/API ports to localhost only.
### Expected operational checks after deploy
1. Unauthenticated `GET /dashboard` returns `401`.
2. Spoofed `x-user-id` does not bypass auth when `AUTH_DISABLED=false`.
3. `/admin/rollover` remains inaccessible from public network.
4. Response headers include anti-framing policy.
## Residual notes
1. Keep production env pinned to:
- `AUTH_DISABLED=false`
- `ALLOW_INSECURE_AUTH_FOR_DEV=false`
2. Keep CORS origins explicitly configured in production:
- `CORS_ORIGIN` and/or `CORS_ORIGINS`.