Files
nick-doc/09 - Audits/Audit Index - 2026-05-24.md
Siavash Sameni 940ad0c655 Add full system audit reports and Telegram Mini App debug handoff
- Three-stream audit (security / logic / performance) with 35+ findings
  derived from actual source code, each with file:line and remediation
- Audit Index cross-references criticals across streams into prioritized
  fix tiers: immediately / before soft launch / before public launch
- Telegram Mini App debug handoff documenting what was implemented and
  all remaining work items with exact file lists and test commands
- Updated architecture, data model, auth API, and registration flow docs
  to reflect Telegram auth, TON wallet, and email verification additions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 17:20:08 +04:00

7.2 KiB

title, tags, created, status
title tags created status
Audit Index — 2026-05-24
audit
index
security
logic
performance
2026-05-24 open

Audit Index — 2026-05-24

Full-system audit triggered by completion of Telegram first-class auth, Request Network integration, rate-limiting enablement, and funds ledger. Three parallel audit streams were run against actual source code.

Report Findings
Security Audit - 2026-05-24 6 critical · 5 high · 7 medium · 4 low
Logic Audit - 2026-05-24 4 critical · 5 high · 7 medium · 2 low
Performance Audit - 2026-05-24 6 high · 8 medium · 4 low

Cross-Cutting Criticals (Fix Immediately)

These items appear in multiple audit streams or are exploitable right now.

ID Severity What Where Fix Effort
SEC-C3 / LOG-CRIT3 CRITICAL Simulated transaction bypass (SIM_*) active in production paymentRoutes.ts:379 1 line — wrap in NODE_ENV !== 'production'
SEC-C4 CRITICAL forceVerifyUser gate is wrong (!== development → unset env passes) authController.ts:1127 1 line — flip to === 'development'
SEC-C1 / SEC-C2 CRITICAL Hardcoded admin password + logged to stdout on every deploy init-admin.ts:7,50 Remove fallback + delete log line + rotate credential
SEC-C5 / LOG-CRIT4 CRITICAL Hardcoded SHKeeper admin credential in source shkeeperPayoutService.ts:224 Move to env var + rotate
SEC-C6 CRITICAL Access and refresh tokens share the same JWT signing secret authService.ts:18,54 Add REFRESH_TOKEN_SECRET env var
LOG-CRIT1 CRITICAL Concurrent webhooks can double-process the same payment (no DB-level lock) paymentCoordinator.ts / shkeeperWebhook.ts Atomic findOneAndUpdate with status guard
LOG-CRIT2 CRITICAL Parallel Telegram auth creates orphan User documents (TOCTOU on link+user creation) authController.ts:377 Upsert link first, create user only if upsert won

High-Priority Queue (Fix Before Soft Launch)

ID Stream What Where
SEC-H2 Security SHKeeper webhook authentication bypass via User-Agent / crypto heuristic shkeeperWebhook.ts:95
SEC-H3 Security Request Network allowTestMode: true hardcoded — test header skips all sig verification requestNetworkRoutes.ts:104
SEC-H5 Security global.io.emit(...) broadcasts financial event data to all connected sockets shkeeperWebhook.ts:546
SEC-H4 Security Typing indicator IDOR — no chat membership check app.ts:267
SEC-H1 Security Telegram in-memory replay map reset on restart; replay possible within 24h window telegramService.ts:395
LOG-HIGH5 Logic verifyEmailWithCode non-atomic User.save + TempVerification.delete authController.ts:620
LOG-HIGH3 Logic refreshTokens[] array grows unboundedly authController.ts:62
LOG-HIGH4 Logic Blocked Telegram user bypasses block when TelegramLink is deleted authController.ts:355
LOG-MED5 Logic Unauthenticated /payment/callback endpoint can mutate any payment status paymentControllerRoutes.ts:20
PERF-H3 Performance Unbounded seller fan-out on new request: User.find({role:'seller'}) + N socket emits PurchaseRequestService.ts:190
PERF-H4 Performance Full chat document (~250 MB for large chats) loaded into memory for every paginated request ChatService.ts:370

Medium Priority (Fix Before Public Launch)

ID Stream What Where
SEC-M1 Security OTP + reset codes logged in plaintext in all environments authController.ts:174,715
SEC-M2 Security Math.random() used for OTP (not CSPRNG) authService.ts:226
SEC-M3 Security No refresh token reuse/theft detection authController.ts:510
SEC-M4 Security Profile update mass-assignment + validateBeforeSave: false authController.ts:921
SEC-M5 Security Login Widget auth has no replay protection (Mini App has it) authController.ts:110
SEC-M6 Security No JWT secret length enforcement at startup config/index.ts:42
LOG-MED1 Logic Funds ledger availability check + append not atomic (concurrent double-release possible) releaseRefundService.ts:37
LOG-MED2 Logic updatePurchaseRequestStatus bypasses state machine validator PurchaseRequestService.ts:551
LOG-MED3 Logic getUserPayments queries userId (wrong field) — always returns empty paymentService.ts:342
LOG-MED4 Logic Payout created without verifying a completed inbound payment exists shkeeperPayoutService.ts:42
PERF-H1 Performance N+1: one Payment.findOne per request row in buyer dashboard PurchaseRequestService.ts:516
PERF-H2 Performance Missing index on Payment.purchaseRequestId models/Payment.ts:190
PERF-M1 Performance Missing compound index (buyerId, createdAt) on PurchaseRequest models/PurchaseRequest.ts:360
PERF-M2 Performance Unanchored regex on title/description — full collection scan PurchaseRequestService.ts:703
PERF-M7 Performance user-online event broadcast to all sockets globally app.ts:300

Low Priority / Hardening

ID Stream What
SEC-L1 Security Passkey challenge debug logs expose all active challenges + all users' passkey IDs
SEC-L2 Security Login attempt counters in-memory (multi-replica bypass possible)
SEC-L3 Security FRONTEND_URL unset allows CORS *
SEC-M7 Security Legacy verifyEmail token route has no expiry check
LOG-LOW1 Logic Duplicate /payment/callback route definition
LOG-MED7 Logic acceptOffer notification uses undefined offer.title
PERF-M3 Performance Double-fetch pattern in update methods (no .lean() on pre-check)
PERF-M6 Performance getSellers() unbounded — no .limit()
PERF-M8 Performance Post-filter after pagination causes wrong totalItems count

Add these to eliminate the collection scans identified in the performance audit:

// models/Payment.ts
paymentSchema.index({ purchaseRequestId: 1, status: 1 });

// models/PurchaseRequest.ts
PurchaseRequestSchema.index({ buyerId: 1, createdAt: -1 });
PurchaseRequestSchema.index({ status: 1, createdAt: -1 });
PurchaseRequestSchema.index({ categoryId: 1, status: 1, createdAt: -1 });
PurchaseRequestSchema.index({ title: 'text', description: 'text', tags: 'text' });

Items Confirmed Correctly Handled (PASS)

  • HMAC timing-safe comparison on all webhooks ✓
  • Telegram initData HMAC derivation and bot account rejection ✓
  • Blocked Telegram user check on existing links ✓
  • Refresh token rotation (old removed before new issued) ✓
  • Password change / reset clears all refresh tokens ✓
  • Socket.IO JWT enforcement on connect ✓
  • join-chat-room membership check ✓
  • bcrypt work factor = 12 ✓
  • WebAuthn challenge consumed on first use ✓
  • All TTL indexes (TempVerification, TelegramSession, Notification) ✓
  • FundsLedgerEntry idempotency key (sparse unique index) ✓
  • SHKeeper polling bounded and self-cleaning ✓
  • Socket.IO room cleanup on disconnect ✓