← Annotated diff Audit · 3 / 4 · Risk register Cải thiện điểm →

🛡️ Implementation Plan — Risk Register

Threads API v2 · prioritized vulnerability → fix mapping · 10 findings (2 critical · 2 high · 4 medium · 2 low)
criticalhigh mediumlow · Priority: P1 now · P2 this week · P3 this sprint · P4 backlog

Risk table

Vulnerability Attack vector Impact Proposed fix Severity Priority
Plaintext passwords in request logs
A09 · logger.ts
Logger serializes full req.body; /auth/login & /auth/register bodies (incl. password) written to every log sink. Mass credential compromise via log access (files, CloudWatch, 3rd-party aggregators, support staff). Remove body from serializer; add pino redact for password, token, authorization. Log only method/url/status. critical P1
Webhook secret & headers logged
A09 · leonardo-webhook.ts
Handler logs JSON.stringify(req.headers) and the raw bearer token on every call. Webhook secret leaks → forged callbacks (trigger image-gen / report flows), token replay. Delete both baseLogger.info lines; at most log a SHA-256 prefix at debug level. critical P1
No brute-force protection on auth
A07 · ratelimit.ts
Single global 100/15min limit; /auth/login open to credential stuffing. In-memory store resets on restart & is per-process. Account takeover via password guessing; limiter ineffective once horizontally scaled (compose runs api+worker). Add a strict per-IP+per-account authLimiter (e.g. 5–10/15min) on /auth/*; move store to Redis (rate-limit-redis). high P2
Weak/default webhook auth (HLS)
A07 · hook-hls.ts
Secret defaults to public 'default_hook_secret_key'; compared with non-constant-time !==. If prod env unset, anyone can forge HLS completion callbacks; timing side-channel on the compare. Require HOOK_SECRET_KEY (no default, min(32)); use crypto.timingSafeEqual; prefer HMAC of payload over static secret. high P2
Upload content-type spoofing
A04/A08 · multer.ts
Validation trusts client file.mimetype; videos reach ffmpeg with no magic-byte check. Malicious/oversized payloads stored in R2; potential parser abuse; storage cost abuse. Verify real type from buffer (file-type), enforce extension allowlist, serve R2 from non-executable path, keep 20MB cap. medium P3
Missing feed composite index
PERF · schema.prisma
Feed query filters isDeleted/isHidden/visibility + sorts createdAt DESC,id DESC with no covering index. Full scan + filesort as posts grows → slow feed, high DB CPU, p95 latency spikes. Add @@index([isDeleted, isHidden, visibility, createdAt, id]); verify with EXPLAIN before/after. medium P3
Counter drift (non-transactional)
INTEGRITY · follower.service.ts
Follow-state write and followersCount +/- are separate DB calls. Permanent desync of denormalized counts on partial failure; wrong follower numbers shown to users. Wrap state-change + counter in transactionService.doInTransaction (pattern already used in post create). medium P3
CORS wildcard allowed
A05 · cors.ts
CORS_ORIGIN='*' is a supported config; permissive if used in prod. Any origin can call the API from a browser context (impact bounded — header-based auth, no cookies). Disallow '*' when NODE_ENV==='production'; require explicit origin allowlist. medium P3
JWT secret floor + unpinned algo
A02 · jwt.service.ts
JWT_SECRET allowed at 1 char; verify() doesn't pin algorithms. Weak-secret brute force; defense-in-depth gap vs algorithm-confusion. z.string().min(32); pass { algorithms:['HS256'] } to jwt.verify. low P4
No observability / attack detection
A09 · cross-cutting
No metrics, tracing, error tracking, or request-correlation IDs; health check doesn't probe Redis/queues. Attacks & outages invisible until users complain; slow incident response. Add request-ID middleware, /metrics (prom-client), Sentry, and a real /health/ready dependency probe. low P4

Sequenced rollout

Phase 1 — Stop the bleeding · ~1–2 hrs · P1

Phase 2 — Harden the auth perimeter · ~half day · P2

Phase 3 — Integrity, performance & config · ~1 day · P3

Phase 4 — Maturity layer · 1–2 weeks · P4 · biggest résumé payoff

Severity model — critical: directly exposes credentials/secrets, trivially exploitable · high: realistic account-takeover or scale-breaking abuse vector · medium: exploitable under specific conditions or degrades correctness/performance at load · low: defense-in-depth & operational hygiene. No SQL-injection, RCE, or production stack-trace leakage was found.