Files
Kordant/piolium/attack-surface/manual-attack-surface-inventory.md
2026-05-29 09:03:47 -04:00

148 lines
8.1 KiB
Markdown

# Manual Attack Surface Inventory: Kordant `web/`
Generated: 2026-05-28
Scope: Kordant web application (SolidStart + tRPC + Drizzle ORM + Stripe + WebSocket)
---
## Entry Points
### HTTP Routes
| Route | Method | Auth | Description | Key File |
|-------|--------|------|-------------|----------|
| `/api/trpc/[trpc]` | POST | Mixed (public/protected/admin) | tRPC endpoint — all tRPC procedures flow here | `web/src/routes/api/trpc/[trpc].ts` |
| `/api/stripe/webhook` | POST | None (Stripe signature) | Stripe webhook handler | `web/src/routes/api/stripe/webhook.ts` |
| `/api/stripe/session-status` | GET | None (public) | Check Stripe checkout session status | `web/src/routes/api/stripe/session-status.ts` |
| `/api/health` | GET | None | Health check | `web/src/routes/api/health.ts` |
| `/api/ready` | GET | None | Readiness check | `web/src/routes/api/ready.ts` |
| `/auth/callback` | GET | None | Clerk OAuth callback | `web/src/routes/auth/callback.tsx` |
| `/billing/checkout` | GET | None | Checkout page | `web/src/routes/billing/checkout.tsx` |
| `/billing/return` | GET | None | Post-payment return page | `web/src/routes/billing/return.tsx` |
### tRPC Routers (16 total, key ones)
| Router | Auth Type | Key Procedures | Key File |
|--------|-----------|----------------|----------|
| `extensionRouter` | Public | `getAuthStatus`, `linkDevice`, `reportPhishing` | `web/src/server/api/routers/extension.ts` |
| `billingRouter` | Protected | `createCheckoutSession`, `createPortalSession`, `cancelSubscription` | `web/src/server/api/routers/billing.ts` |
| `adminRouter` | Admin | `blogCreate`, `blogUpdate`, `userUpdateRole`, `stats` | `web/src/server/api/routers/admin.ts` |
| `voiceprintRouter` | Protected | `createEnrollment`, `analyzeAudio` | `web/src/server/api/routers/voiceprint.ts` |
| `darkwatchRouter` | Protected | `addWatchlistItem`, `runScan` | `web/src/server/api/routers/darkwatch.ts` |
| `userRouter` | Protected | Profile management | `web/src/server/api/routers/user.ts` |
| `reportsRouter` | Protected | Report generation | `web/src/server/api/routers/reports.ts` |
| `spamshieldRouter` | Protected | Spam analysis | `web/src/server/api/routers/spamshield.ts` |
### WebSocket
| Endpoint | Auth | Description | Key File |
|----------|------|-------------|----------|
| `ws://host:3001/?token=<JWT>` | JWT in query param | Real-time alert broadcast | `web/src/server/websocket.ts` |
---
## Public Routes / URLs (No Auth Required)
1. `/api/trpc/extension.getAuthStatus` — Public tRPC query
2. `/api/trpc/extension.linkDevice` — Public tRPC mutation
3. `/api/trpc/extension.reportPhishing` — Public tRPC mutation
4. `/api/stripe/webhook` — Stripe webhook (signature-verified, no user auth)
5. `/api/stripe/session-status` — Stripe session status check
6. `/auth/callback` — Clerk OAuth callback
7. `/billing/checkout` — Stripe Checkout page
8. `/billing/return` — Post-payment return
9. `/api/health`, `/api/ready` — Health checks
10. Static pages: `/`, `/pricing`, `/features`, `/blog`, `/privacy`, `/terms`, `/about`, `/ads`
---
## Attacker Sources
| Source | Capability | Access Level |
|--------|-----------|-------------|
| External attacker (internet) | Send HTTP requests, craft tRPC payloads, spoof Stripe webhooks, connect to WebSocket | Unauthenticated |
| Compromised browser extension | Make tRPC calls with stored API key | Authenticated (as extension-linked user) |
| Insider (non-admin user) | Access to own data via tRPC, WebSocket | Authenticated (user role) |
| Insider (admin) | Full admin panel, blog management, user role changes | Authenticated (admin role) |
---
## Sinks
| Sink | File | Description | Risk |
|------|------|-------------|------|
| Drizzle ORM queries | Multiple routers | SQL execution via `db.select`, `db.insert`, `db.update`, `db.delete` | SQL injection if user input reaches query builders |
| Stripe API calls | `billing.service.ts`, `stripe.ts` | Payment operations, subscription management | Payment manipulation, webhook replay |
| File system (audio) | `voiceprint/storage.ts` | `writeFile` for audio storage | Path traversal, disk exhaustion |
| File system (reports) | `reports/generator.ts` | `writeFileSync` for PDF output | Path traversal |
| Puppeteer | `reports/generator.ts` | `page.setContent(html)` — renders HTML to PDF | SSRF, XSS via crafted HTML |
| External API calls | `darkwatch/scan.engine.ts` | `fetch()` to HIBP, SecurityTrails, Censys, Shodan | SSRF if user-controlled URLs reach fetch |
| WebSocket messages | `websocket.ts` | `ws.send()` for alert broadcast | Alert flooding |
| Database writes (webhook) | `billing.service.ts` | `db.insert(subscriptions)` on webhook events | Duplicate subscription creation |
---
## Hidden Control Channels
| Channel | File | Description | Risk |
|---------|------|-------------|------|
| `process.env.APP_URL` | `middleware.ts` | Trusted as CORS origin | CORS origin injection if env is mutable |
| `process.env.STRIPE_WEBHOOK_SECRET` | `webhook.ts` | Stripe signature verification key | Webhook replay if key is leaked |
| JWT in `?token=` query param | `websocket.ts` | WebSocket auth token visible in logs | Token leakage via proxy/access logs |
| Rate limiter path heuristic | `utils.ts` | `path.includes(p)` for sensitive paths | Rate limit bypass via path manipulation |
| `scanStates` Map (in-memory) | `darkwatch.service.ts` | Scan state stored in process memory | State loss on restart, no persistence |
| `userSockets` Map (in-memory) | `websocket.ts` | Socket connections stored in process memory | Memory exhaustion, no connection limit per user |
---
## Middleware / Proxy Assumptions
| Layer | File | Assumption | Break Impact |
|-------|------|-----------|-------------|
| Security headers | `middleware.ts` | Sets CSP, HSTS, X-Frame-Options, etc. | Missing headers weaken defense-in-depth |
| CORS | `middleware.ts` | Validates origin against whitelist | CORS misconfiguration if APP_URL is attacker-controlled |
| Clerk auth | `middleware.ts` | Sets `ctx.user` from Clerk session | Auth bypass if Clerk session validation fails |
| tRPC procedure types | `utils.ts` | `publicProcedure`, `protectedProcedure`, `adminProcedure` enforce auth | Privilege escalation if middleware is bypassed |
| Rate limiting | `utils.ts` | Redis sorted set, tier-based limits | DoS if rate limit is bypassed |
| Valibot schemas | `schemas/*.ts` | Input validation before service layer | Injection if schema is missing or weak |
---
## Key Files
### Authentication & Authorization
- `web/src/middleware.ts` — Clerk middleware, security headers, CORS
- `web/src/server/api/utils.ts` — tRPC procedure types, rate limiting middleware
- `web/src/server/auth/jwt.ts` — JWT verification
- `web/src/server/auth/session.ts` — Session management
### Stripe / Billing
- `web/src/routes/api/stripe/webhook.ts` — Stripe webhook entry point
- `web/src/server/services/billing.service.ts` — Billing service (webhook handler, checkout, subscriptions)
- `web/src/server/stripe.ts` — Stripe client initialization
- `web/src/server/api/schemas/billing.ts` — Billing input schemas
### tRPC Routers
- `web/src/server/api/routers/admin.ts` — Admin procedures (blog, users)
- `web/src/server/api/routers/billing.ts` — Billing procedures
- `web/src/server/api/routers/extension.ts` — Extension procedures (PUBLIC)
- `web/src/server/api/routers/voiceprint.ts` — Voice print procedures
- `web/src/server/api/routers/darkwatch.ts` — DarkWatch procedures
### Services
- `web/src/server/services/voiceprint.service.ts` — Voice analysis pipeline
- `web/src/server/services/voiceprint/storage.ts` — Audio file storage
- `web/src/server/services/darkwatch.service.ts` — DarkWatch scan orchestration
- `web/src/server/services/darkwatch/scan.engine.ts` — External API scanning
- `web/src/server/services/reports/generator.ts` — Report generation (Puppeteer)
### Real-Time
- `web/src/server/websocket.ts` — WebSocket server (port 3001)
### Database
- `web/src/server/db/index.ts` — Drizzle ORM database connection
- `web/src/server/db/schema/*.ts` — Database schema definitions
### Rate Limiting
- `web/src/server/lib/ratelimit.ts` — Redis-based rate limiter