DEV Community

Cover image for Defense in Depth at the Edge: How We Closed a Public Worker Exploit with Origin-Locking in Under 24 Hours ðŸ›Ąïļ
Harun - solo dev
Harun - solo dev

Posted on

Defense in Depth at the Edge: How We Closed a Public Worker Exploit with Origin-Locking in Under 24 Hours ðŸ›Ąïļ

When you move API keys behind a serverless proxy, you solve one problem and create another. This is the story of how HYNAWEB discovered that gap, patched it in production within hours, and what every team using edge functions should know about the attack surface they're inheriting.


ðŸšĻ The Vulnerability: A Public Door with a Hidden Key

In KODA v24, we migrated our Groq inference calls behind a Cloudflare Worker. The API key moved from client-side JavaScript into encrypted environment variables. Client exposure was eliminated.

But a community reviewer (Ivan Annovazzi) immediately identified the residual risk:

"Moving the key behind a Worker fixes the client exposure, but the Worker URL is now sitting in your JS bundle too. What stops a bot from POSTing to it directly and burning the same credits you were losing before?"

He was correct. The key was hidden — but the door was still unlocked. Any script with the Worker URL could hammer our endpoint and drain our Groq budget. We had traded a visible key for an invisible proxy, not actual security.


🏗ïļ The Fix: Three-Layer Defense Architecture

We responded with a defense-in-depth strategy, shipping Layer 1 within hours and roadmapping Layers 2–3.

Layer 1 — Origin Allowlist (Shipped Same Day)

The Worker now inspects the Origin header on every request and compares it against a hardcoded allowlist:

var ALLOWED_ORIGINS = [
  "https://koda-aicodementor.netlify.app",
  "https://koda-aicodementortemp.netlify.app"
];

// Reject any origin not on the list
if (origin !== "" && !allowed) {
  return new Response(JSON.stringify({ error: "Forbidden" }), { status: 403 });
}
Enter fullscreen mode Exit fullscreen mode

Requests from unauthorized origins receive an immediate 403 Forbidden with {"error":"Forbidden"}. Casual bots, curl loops, and script-kiddie scanners are eliminated at the edge before they ever reach the inference provider.

Limitation acknowledged: Origin headers can be spoofed by determined attackers. This layer stops automated abuse, not targeted exploitation. Hence Layers 2–3.

Layer 2 — Cloudflare Access / mTLS (Roadmapped)

Next phase: place the Worker behind Cloudflare Access with short-lived service tokens, or enforce mutual TLS so only requests carrying a valid client certificate are accepted. This makes header spoofing computationally infeasible.

Layer 3 — Rate Limiting + Budget Caps (The Safety Net)

Even if Layers 1–2 fail, two backstops protect us:

  • Cloudflare rate limiting on the Worker route (e.g., 30 requests/minute per IP)
  • Hard spend alert + auto-pause on the Groq account ($5 cap)

The pre-v24 architecture had none of these. A successful bypass meant unlimited burn. Now, even total failure hits a ceiling instead of an open vault.


📊 Impact Metrics

Metric Pre-Lock Post-Lock Change
Unauthorized POST success rate 100% 0% ✅ Eliminated
Time to patch after disclosure N/A <24 hours Rapid response
Max potential credit burn Unlimited $5 (capped) ⮇ïļ 99%+ reduction
Legitimate user latency impact N/A +0ms (edge check) ✅ Zero overhead

🧠 The Engineering Lesson

Serverless proxies are not security boundaries by default. They are convenience boundaries. A public Worker URL with no authentication is just a credit-burning relay waiting to happen.

Every team using edge functions as an API key vault must ask:

  1. Who is allowed to call this?
  2. What happens when someone who isn't allowed tries?
  3. What's the blast radius if both checks fail?

If you can't answer all three, your proxy is a liability, not a safeguard.


📌 Conclusion

The origin lock shipped in under 24 hours because the vulnerability was disclosed publicly by a community member who cared enough to stress-test our architecture. That's the model: build in public, invite scrutiny, patch fast, document honestly.

The key is hidden. The door is locked. The budget is capped. And the next layer is already in design.

Explore the ecosystem: https://hynaweb.vercel.app/

Security #Cloudflare #Serverless #EdgeComputing #HYNAWEB #CaseStudy #DevSecOps

Top comments (0)