You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Harden the feedback worker against abuse: validate and sanitize all inputs, enforce strict rate limits, protect against CSRF, and ensure no secrets leak in responses or logs.
User story
As a developer, I want the feedback worker to be secure against common web attack vectors so that bad actors cannot spam issues, inject malicious content, or extract secrets through the feedback endpoint.
Context
The feedback worker (#109) is a public HTTP endpoint that creates GitHub issues and calls the Anthropic API. Without hardening it is a potential abuse surface. This story applies OWASP Top 10 mitigations appropriate for a Cloudflare Worker context.
Part of: #46
Depends on: #109 (worker core must exist first)
Acceptance criteria
Input validation (OWASP A03 — Injection)
All string fields (title, description, suggestedTranslation, etc.) sanitized: strip HTML tags, null bytes, control characters before processing
Submissions rejected by content policy logged internally (for monitoring) but return a generic 422 to the caller — no leaking of which rule triggered
Headers
Worker sets X-Content-Type-Options: nosniff on all responses
Worker does not expose Server header or Cloudflare worker internals
Technical notes
JSON schema validation: use ajv or a lightweight alternative compatible with Cloudflare Workers runtime (no Node.js built-ins)
IP hashing: crypto.subtle.digest('SHA-256', encoder.encode(ip)) — available in Workers runtime
Distributed burst limit: requires Cloudflare Durable Objects (strongly consistent counter) or accept KV eventual consistency risk (document the trade-off decision)
Prompt injection: add a check in the Claude validation prompt instructing Claude to flag any submission that appears to be attempting to override its instructions
Test coverage
Unit tests
Title > 200 chars returns 400
Description > 5000 chars returns 400
Unknown appId returns 400, no GitHub or Anthropic API calls made
Malformed JSON returns 400
Non-allowlisted Origin header returns 403
Content-Type not application/json returns 415
IP hash: confirm raw IP is not stored in KV
E2E tests
Rate limit: 6th submission within window returns 429 with Retry-After header
Performance
Input validation (schema check + sanitization) adds < 5 ms overhead to request processing
Regression
Valid submissions still succeed end-to-end after all hardening is applied
Documentation to update
CLAUDE.md — add security posture section for cloudflare/feedback-worker/ documenting rate limit config, CORS config, and secret names
cloudflare/feedback-worker/wrangler.toml — comment block listing all required secrets and their purpose
Unknowns / needs investigation
Cloudflare Workers AJV compatibility — verify which JSON schema libraries work in the Workers runtime without bundling Node.js polyfills
Durable Objects cost/complexity vs. KV eventual consistency for the distributed burst limit — make explicit decision and document
Out of scope
WAF rules at the Cloudflare zone level (out of scope for this codebase — a network-level concern)
DDoS mitigation (Cloudflare handles this at the platform level)
In plain English
Harden the feedback worker against abuse: validate and sanitize all inputs, enforce strict rate limits, protect against CSRF, and ensure no secrets leak in responses or logs.
User story
As a developer, I want the feedback worker to be secure against common web attack vectors so that bad actors cannot spam issues, inject malicious content, or extract secrets through the feedback endpoint.
Context
The feedback worker (#109) is a public HTTP endpoint that creates GitHub issues and calls the Anthropic API. Without hardening it is a potential abuse surface. This story applies OWASP Top 10 mitigations appropriate for a Cloudflare Worker context.
Part of: #46
Depends on: #109 (worker core must exist first)
Acceptance criteria
Input validation (OWASP A03 — Injection)
title,description,suggestedTranslation, etc.) sanitized: strip HTML tags, null bytes, control characters before processingappIdvalidated against an allowlist (gaming_app,book_app) — unknown values return 400 immediately (no downstream calls)typevalidated against allowlist (bug,feature,localization) — unknown values return 400locale(for localization type) validated against BCP 47 formatRate limiting (OWASP A04 — Insecure Design)
Retry-AfterheaderCSRF protection
Access-Control-Allow-Originrestricted toALLOWED_ORIGINSenv var values — wildcard*not permittedContent-Type: application/jsonenforced — requests with other content types rejected with 415Originheader validated againstALLOWED_ORIGINSon every POST requestSecrets management
ANTHROPIC_API_KEYandGITHUB_TOKENstored only as Cloudflare Worker secrets (viawrangler secret put) — confirmed not in source orwrangler.tomlAbuse / content policy
Headers
X-Content-Type-Options: nosniffon all responsesServerheader or Cloudflare worker internalsTechnical notes
ajvor a lightweight alternative compatible with Cloudflare Workers runtime (no Node.js built-ins)crypto.subtle.digest('SHA-256', encoder.encode(ip))— available in Workers runtimeTest coverage
Unit tests
appIdreturns 400, no GitHub or Anthropic API calls madeOriginheader returns 403application/jsonreturns 415E2E tests
Retry-AfterheaderPerformance
Regression
Documentation to update
CLAUDE.md— add security posture section forcloudflare/feedback-worker/documenting rate limit config, CORS config, and secret namescloudflare/feedback-worker/wrangler.toml— comment block listing all required secrets and their purposeUnknowns / needs investigation
Out of scope
Dependencies
Definition of done