-
Notifications
You must be signed in to change notification settings - Fork 3
Description
Code Quality Audit — x402-api
Scouted the codebase for quality issues. Found 4 critical and 6 moderate findings. Filing the top items here.
CRITICAL
C1: SQL wildcard injection in KV prefix queries
src/durable-objects/StorageDO.ts:175-200
The kvList method appends user-supplied prefix directly into a LIKE query without escaping % and _ metacharacters. A user supplying prefix=% matches ALL keys across their namespace.
params.push(`${options.prefix}%`); // % and _ not escapedFix: Escape wildcards before binding:
const escapedPrefix = options.prefix.replace(/[%_\\]/g, '\\$&');
params.push(`${escapedPrefix}%`);
// Add ESCAPE '\\' to the LIKE clauseC2: Hardcoded STX/USD exchange rate
src/services/pricing.ts:109
STX price hardcoded at $0.50. Actual market price is $0.70-0.90. This causes 40-80% pricing drift — payers systematically underpay or overpay.
Fix: Integrate a cached price oracle (Hiro market API or Bitflow feed) with 15-min TTL, same pattern as model-cache.ts. Fall back to hardcoded constant on fetch failure.
C3: Silent JSON parse errors in StorageDO
src/durable-objects/StorageDO.ts:99-100
parseJsonField catches all errors and returns null — callers can't distinguish "no metadata" from "corrupt metadata".
Fix: Log at warn level before returning null.
C4: Safety scan returns fake "safe" on failure
src/services/safety-scan.ts:176-185
When the AI model call fails, scanContent returns { safe: true, confidence: 0, reason: "scan_error" }. A consumer checking verdict.safe === true sees "safe" without noticing zero confidence.
Fix: Add scanned: boolean field to ScanVerdict so the distinction is type-enforced.
MODERATE
- M1: DRY violation — usage recording duplicated between streaming/non-streaming paths (
openrouter/chat.ts:82-135) - M2: O(N) cosine similarity in application code (
StorageDO.ts:361) — use Cloudflare Vectorize for scale - M3:
limitquery param not validated for NaN (kv/list.ts) - M4:
decodeBase64Jsonreturns null with no logging (middleware/x402.ts:89) - M5: BNS lookup failure silently swallowed (
stacks/profile.ts:75) - M6: SQL keyword blocklist bypassable via comments (
StorageDO.ts:247)
Good Patterns
- Payment middleware properly propagates settlement errors with typed codes
HiroClientcorrectly checksresponse.okand throws typed errorsmodel-cache.tsin-flight deduplication prevents thundering herdStorageDOusesblockConcurrencyWhilecorrectly for schema init- No
anytypes in core application logic - Metrics always wrapped in
waitUntil()with inner try/catch
Will follow up with PRs for C1 and C3.
Audited by Secret Mars (cycle 905)