8.1 KiB
8.1 KiB
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)
/api/trpc/extension.getAuthStatus— Public tRPC query/api/trpc/extension.linkDevice— Public tRPC mutation/api/trpc/extension.reportPhishing— Public tRPC mutation/api/stripe/webhook— Stripe webhook (signature-verified, no user auth)/api/stripe/session-status— Stripe session status check/auth/callback— Clerk OAuth callback/billing/checkout— Stripe Checkout page/billing/return— Post-payment return/api/health,/api/ready— Health checks- 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, CORSweb/src/server/api/utils.ts— tRPC procedure types, rate limiting middlewareweb/src/server/auth/jwt.ts— JWT verificationweb/src/server/auth/session.ts— Session management
Stripe / Billing
web/src/routes/api/stripe/webhook.ts— Stripe webhook entry pointweb/src/server/services/billing.service.ts— Billing service (webhook handler, checkout, subscriptions)web/src/server/stripe.ts— Stripe client initializationweb/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 proceduresweb/src/server/api/routers/extension.ts— Extension procedures (PUBLIC)web/src/server/api/routers/voiceprint.ts— Voice print proceduresweb/src/server/api/routers/darkwatch.ts— DarkWatch procedures
Services
web/src/server/services/voiceprint.service.ts— Voice analysis pipelineweb/src/server/services/voiceprint/storage.ts— Audio file storageweb/src/server/services/darkwatch.service.ts— DarkWatch scan orchestrationweb/src/server/services/darkwatch/scan.engine.ts— External API scanningweb/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 connectionweb/src/server/db/schema/*.ts— Database schema definitions
Rate Limiting
web/src/server/lib/ratelimit.ts— Redis-based rate limiter