Exploit Vulnerable API and Infra
Chase one missing dependency injection through three exposed endpoints — broken access control that leaks a flag straight from logs, and an SSRF that reaches it a second way — in a disposable local sandbox.
PremiumProblem
A single missing line of code can expose an entire admin surface. It's common to build an authorization dependency correctly (a function that validates an `X-Admin-Token` header and rejects the request if it's missing or wrong) and then simply forget to attach it to one or more routes when they're registered on the router. The dependency exists, is unit-tested, and looks correct in isolation — but if it was never wired into the router for a given endpoint, that endpoint authenticates nobody. This is **broken access control** (OWASP API1/API5, "Broken Object/Function Level Authorization"), and it's one of the most common real-world API vulnerabilities precisely because it's invisible in a code review that only looks at the dependency function itself. Once you've found an admin panel with no authentication, the blast radius often extends further than "read some data" — an endpoint that fetches a URL on the server's behalf, meant only for internal use, can become a **Server-Side Request Forgery (SSRF)** primitive: a way to make the server itself issue a request to an internal-only resource that a normal client could never reach directly. In this lab you'll run the **DARE Vulnerable AI Suite** locally and attack its `vulnerable-api-infra` challenge: a single root cause (one unauthenticated route dependency) exposed through three separate paths — a sessions endpoint, a logs endpoint that leaks a secret directly, and a webhook-preview endpoint that leaks the same secret again via SSRF. > Practice only against the disposable `dare-vulnerable-ai` suite running > locally on `127.0.0.1:8000` (bound to localhost only), with synthetic > logs and internal endpoints. Never attempt broken-access-control or > SSRF probing against a real API, cloud metadata endpoint, or any > system you do not own or have explicit written authorization to test.
Objectives
By the end of this lab you will be able to:
- Explain broken function-level access control and why "the
dependency exists" is not the same guarantee as "the dependency is
attached to this route." - Probe an admin API without credentials to determine whether
authentication is actually enforced. - Recognize sensitive data (a secret token) leaking through an
unexpected channel — application logs — rather than a typical
response field. - Explain SSRF and demonstrate it by making a server fetch an
internal-only URL on your behalf. - Trace three different exposed endpoints back to one shared root
cause, and explain why a one-line fix (attaching the missing
dependency) closes all three at once.
Prerequisites
To complete this lab you'll need:
- Docker and Docker Compose installed.
- Access to the private
dare-vulnerable-airepository (enrolled
students have access):git@github.com:darelabs-tech/dare-vulnerable-ai.git. -
curl(or an equivalent HTTP client) and a terminal. - Basic familiarity with HTTP headers and JSON request bodies; no
prior infrastructure-security experience required.
One root cause, three exposures
require_admin_token() ← exists, correctly checks X-Admin-Token, unit-tested
Router registration:
/api/admin/panel/sessions ──▶ dependency NOT attached
/api/admin/panel/logs ──▶ dependency NOT attached
/api/admin/panel/integrations/webhook-preview ──▶ dependency NOT attached
None of these routes are missing an authorization concept — the
require_admin_token dependency is real code that would reject an
unauthenticated request if it were actually wired into the router for
these paths. It just wasn't attached when these three routes were
registered. That's the entire bug: not a flawed check, a check that
was never plugged in.
Why this is dangerous beyond "you can read some data"
-
sessionsproves the pattern: anyone, with no header at all, gets a
200. -
logsturns "no auth" into a direct secret leak — application logs
often contain more than developers intend (a token logged "just for
this one debug line" that never got removed), and with no access
control, that becomes public. -
webhook-previewturns "no auth" into SSRF: it accepts aurl
and fetches it server-side to build a preview. The internal endpoint
it can reach,/internal/ops-metadata, is designed to only accept
requests that originate from the host itself — a direct external
curlto it gets a403. But the webhook-preview endpoint runs
inside the server, so when it fetches that same URL on the
server's behalf, the request looks like it came from the host, and
it succeeds. The access control that correctly protects
/internal/ops-metadatafrom the outside world does nothing against
a request forged from the inside.
How you'll work through this lab
- Unlock the challenge.
- Hit
/sessionswith zero headers and prove nothing is enforced. - Hit
/logswith zero headers and find the flag leaking directly. - Confirm
/internal/ops-metadatarefuses a direct external call
(403), then reach it anyway throughwebhook-preview(SSRF) and
get the same flag a second way. - Read the official solution and explain why this is one root cause,
not three separate bugs.