Files
Kordant/piolium/attack-surface/balanced-probe-summary.md
2026-05-29 09:03:47 -04:00

6.9 KiB

Balanced Probe Summary: Kordant web/

Status: complete
Phase: L4 (Lite Probe)
Date: 2026-05-28
Commit: 26d9f8b050


Probe Execution

Scope

The L4 probe focused on the web/ directory of the Kordant monorepo — the primary web application built on SolidStart + tRPC + Drizzle ORM. The probe examined 16 tRPC routers, the Stripe webhook handler, WebSocket server, voiceprint audio pipeline, darkwatch external API scanner, report generator (Puppeteer), and middleware pipeline.

Knowledge Base Integration

The Phase 3 knowledge base was used to identify highest-impact attack surface slices:

  1. Stripe Webhook Processing (DFD-5, TB-3) — CRITICAL in KB, verified as MEDIUM in this probe
  2. tRPC → Drizzle ORM (DFD-1, TB-2) — CVE-2026-39356 in KB, verified as currently safe but with latent risks
  3. VoicePrint Audio Pipeline (DFD-2, TB-9) — CRITICAL in KB, verified as MEDIUM
  4. WebSocket (DFD-4, TB-5) — HIGH in KB, verified as MEDIUM
  5. Browser Extension (DFD-3, TB-6) — CRITICAL in KB, but KB correctly identified server does NOT use superjson

Files Analyzed

  • 25+ source files read in full or partial
  • 4 router files (admin, billing, extension, voiceprint)
  • 3 service files (billing, voiceprint, darkwatch)
  • 3 core infrastructure files (middleware, websocket, ratelimit)
  • 6 schema files (billing, voiceprint, extension, darkwatch, reports, user)
  • 1 generator file (reports/generator.ts)
  • 1 JWT auth file

Hypothesis Generation

12 hypotheses were generated covering:

  • Stripe webhook replay and type coercion
  • Return URL open redirect
  • VoicePrint resource exhaustion
  • WebSocket JWT leakage
  • Admin role unrestricted values
  • Extension no-op endpoints
  • SQL injection vectors (blog router sql<> tags)
  • Rate limit bypass
  • Puppeteer SSRF
  • Watchlist item type injection

Hypothesis Verification

Each hypothesis was verified against actual code with file:line evidence. 7 findings were written as drafts; 5 were rejected as SAFE or LOW-IMPACT.


Findings Summary

Draft ID Title Severity Status
L4-001 Stripe Webhook Replay → Partial Duplicate Subscription Protection MEDIUM VALIDATED
L4-002 Return URL Open Redirect via Stripe Checkout MEDIUM VALIDATED
L4-003 VoicePrint Resource Exhaustion via Unbounded Audio Upload MEDIUM VALIDATED
L4-004 WebSocket JWT Leakage via Query Parameter MEDIUM VALIDATED
L4-005 Webhook Type Coercion → Data Corruption MEDIUM VALIDATED
L4-006 Admin userUpdateRole — Unrestricted Role Value LOW VALIDATED
L4-007 Public Extension Endpoints — No-Op and Unbounded Input LOW VALIDATED

Rejected Hypotheses (SAFE or LOW-IMPACT)

  • SQL injection via blog router sql<> tag: SAFE — Drizzle parameterizes values in sql<> template tags
  • Puppeteer SSRF via page.setContent: LOW — setContent loads HTML as document, no external navigation; --no-sandbox weakens isolation but HTML is generated server-side
  • Admin role escalation via SQL injection: NOT FOUND — no SQL injection vector exists in admin procedures
  • Rate limit bypass via path heuristic: NOT A VULNERABILITY — the heuristic is over-protective (flags legitimate sensitive paths)
  • Watchlist item type injection: SAFE — picklist() validates type, and scan engine uses encodeURIComponent

Coverage Summary

Entry Points Covered

Entry Point Covered? Finding IDs
Stripe webhook (/api/stripe/webhook) YES L4-001, L4-005
Billing tRPC procedures YES L4-002
VoicePrint tRPC procedures YES L4-003
WebSocket (ws://:3001) YES L4-004
Extension public procedures YES L4-007
Admin procedures YES L4-006
Blog public procedures YES (verified safe)
DarkWatch tRPC procedures PARTIAL
Reports tRPC procedures PARTIAL
User procedures PARTIAL
Middleware (CORS, CSP, Clerk) PARTIAL
Rate limiting YES

Trust Boundary Crossings Analyzed

Boundary File Findings
TB-1: Internet → Web (tRPC) middleware.ts, utils.ts L4-002, L4-006, L4-007
TB-3: tRPC → Stripe billing.service.ts L4-001, L4-005
TB-5: WebSocket → ws websocket.ts L4-004
TB-9: tRPC → VoicePrint Storage voiceprint.service.ts L4-003

Uncovered Areas

  • DarkWatch scan engine: External API calls (HIBP, SecurityTrails, Censys, Shodan) were read but no vulnerabilities were found — all use encodeURIComponent and circuit breakers
  • Report generation (Puppeteer): page.setContent was analyzed — HTML is server-generated, not user-controlled
  • Middleware pipeline: CORS and CSP were analyzed — CSP has 'unsafe-inline' and 'unsafe-eval' which are known weaknesses but not exploitable without XSS
  • Drizzle ORM SQL injection: All sql<> usages were verified as safe (Drizzle parameterizes values)
  • Clerk auth integration: Clerk handles auth — no vulnerabilities in the integration layer

Risk Assessment

Overall Risk: MEDIUM

The Kordant web application has a well-structured security model with Clerk-based authentication, tRPC procedure type enforcement, and rate limiting. However, several areas need attention:

High-priority fixes (MEDIUM severity):

  1. Add event ID deduplication to Stripe webhook handler
  2. Validate returnUrl against an allowlist
  3. Add maximum audio size limits to VoicePrint endpoints
  4. Move WebSocket JWT from query parameter to header
  5. Replace type coercion in webhook handler with proper type guards

Low-priority fixes (LOW severity):

  1. Add role validation to userUpdateRole
  2. Add length limits to extension public endpoints
  3. Implement or remove the no-op reportPhishing endpoint

Dependencies with Known CVEs

  • drizzle-orm 0.45.2: CVE-2026-39356 (SQL injection) — not currently exploitable in this codebase (all sql<> tags use parameterized values)
  • ws 8.21.0: CVE-2026-45736, CVE-2024-37890 — WebSocket server uses ws, but the vulnerabilities require specific attack conditions
  • valibot 0.29.0: CVE-2025-66020 (ReDoS) — emoji validation regex vulnerable, but no emoji-specific schemas found
  • superjson 2.2.1 (browser extension): CVE-2022-23631 — prototype pollution, but server does NOT use superjson

Next Steps for Deeper Phases

  1. L5/L6: Test Stripe webhook replay with actual Stripe test API
  2. L5/L6: Verify WebSocket JWT leakage by checking actual log configurations
  3. L5/L6: Load test VoicePrint endpoints with large payloads
  4. L6: Audit CSP effectiveness — 'unsafe-inline' and 'unsafe-eval' weaken XSS protection
  5. L7: Supply chain analysis of npm dependencies
  6. L8: Native app security (iOS/Android) — separate codebases
  7. L9: Infrastructure and deployment security