Finding 3/6: Execution was trusted. SSRF said Hi.
Server-Side Request Forgery via Client-Controlled pccs_url in dstack-verifier
Severity: High
Affected component: dstack-verifier /verify endpoint
dstack's attestation verifier shipped with an unauthenticated SSRF vulnerability. This write-up covers the technical behavior and real-world implications of the flaw.
The issue was identified by Bluethroat Labs and responsibly disclosed to Phala Network in January 2026.

Executive Summary
- The
dstack-verifierservice accepted a client-controlledpccs_urlparameter on its unauthenticated/verifyendpoint. - This URL was used directly as the base address for multiple server-side HTTP requests when fetching DCAP collateral, with no validation, no allowlist, and TLS verification disabled.
- An attacker with network access to the verifier could force outbound requests to arbitrary internal hosts, including cloud metadata endpoints, internal services, and link-local addresses.
Why This Matters: The Capital One Precedent
This is the same vulnerability class that caused the 2019 Capital One breach, one of the largest data breaches in US financial history. In that incident, an attacker exploited SSRF to reach the AWS EC2 metadata endpoint (169.254.169.254), extracted IAM role credentials, and used them to exfiltrate over 100 million customer records including Social Security numbers, bank account numbers, and credit scores. Capital One paid $80 million in regulatory fines and $190 million in class-action settlements.
The PoC for this finding targets the exact same endpoint:
curl -X POST http://<verifier-host>:8080/verify \
-H "Content-Type: application/json" \
-d '{
"quote": "00",
"event_log": "[]",
"vm_config": "{}",
"pccs_url": "http://169.254.169.254/latest/meta-data/"
}'SSRF against cloud metadata services is not theoretical. It is one of the most reliably exploited vulnerability classes in cloud-deployed applications.
Vulnerability Details
The /verify endpoint accepted a VerificationRequest containing a client-controlled pccs_url:
// types.rs
pub struct VerificationRequest {
pub quote: String,
pub event_log: String,
pub vm_config: String,
pub pccs_url: Option<String>, // Client-controlled, no validation
pub debug: Option<bool>,
}This value flowed through the verification pipeline without any validation or sanitization:
POST /verify { pccs_url: "http://attacker-controlled" }
|
v
CvmVerifier::verify(&request)
|
v
verify_quote(attestation, &request.pccs_url)
|
v
get_collateral(pccs_url, quote)
|
v
client.get(endpoints.url_*()).send() // 4 separate HTTP requests to attacker URLThe collateral-fetching logic issued four distinct HTTP requests using the attacker-supplied base URL (PCK CRL, TCB Info, QE Identity, and PCK certificate). The HTTP client was configured with danger_accept_invalid_certs(true), meaning it would happily connect to internal services with self-signed or expired certificates.
What Made This Exploitable by Default
This was not a hardening gap that required unusual deployment choices. The shipped defaults made the service vulnerable out of the box:
- Bound to all interfaces:
dstack-verifier.tomlshipped withaddress = "0.0.0.0". - No authentication: The
/verifyendpoint required no credentials. The README demonstrated directcurlaccess. - Docker published the port: The Dockerfile included
EXPOSE 8080and the Docker Compose example mapped8080:8080. - TLS verification disabled:
danger_accept_invalid_certs(true)on the HTTP client.
Following the official deployment guide produced a network-accessible, unauthenticated SSRF oracle.
Impact
From the verifier's network position, an attacker could:
- Reach cloud metadata services (
169.254.169.254) to extract IAM credentials, API tokens, and instance identity documents. - Probe internal network topology using timing and error differentials across requests.
- Interact with internal services that trust requests from the verifier's network segment.
- Bypass network segmentation since the verifier acts as a proxy from the external network into the internal one.
In a cloud deployment (the primary deployment model for dstack), access to the metadata endpoint is often sufficient to escalate from SSRF to full credential theft.
Fix
Remove the pccs_url field from the public API entirely, requiring the PCCS URL to be configured server-side only. If client-specified PCCS URLs are operationally required, enforce a strict allowlist of permitted hosts in the server configuration.
Timeline
| Date | Event |
|---|---|
| January 6, 2026 | Vulnerability reported to Phala Network |
| January 2026 | Acknowledged and triaged |
Key Takeaway
Do not let untrusted input control the destination of server-side HTTP requests. This is SSRF 101 and it remains one of the most exploited vulnerability classes in cloud environments precisely because the blast radius is so large. The Capital One breach proved that a single SSRF endpoint can compromise an entire organization's data. This verifier had the same exposure by default.
References
- Capital One Breach (2019): SSRF to cloud metadata endpoint, 100M+ records exfiltrated, $80M OCC fine
- OWASP SSRF: A10_2021-Server-Side_Request_Forgery_(SSRF)
This vulnerability was discovered by Rahul Saxena of Bluethroat Labs during a security assessment of the dstack ecosystem. Responsible disclosure was coordinated with Phala Network.
For a public timeline of the disclosure process, see: x.com/saxenism/status/2021943382155899351.
