Skip to content

Server-Side Request Forgery (SSRF) in Dragonfly2 Scheduler DownloadTinyFile

Critical
gaius-qi published GHSA-fhf9-m53m-863g Jun 9, 2026

Package

gomod d7y.io/dragonfly/v2 (Go)

Affected versions

<= 2.4.3

Patched versions

2.4.4-rc.3

Description

Advisory Details

Title: Server-Side Request Forgery (SSRF) in Dragonfly2 Scheduler DownloadTinyFile

Description:

Summary

An unauthenticated Server-Side Request Forgery (SSRF) vulnerability exists in the Dragonfly2 Scheduler's DownloadTinyFile component. The HTTP client responsible for downloading "tiny" piece data from peer nodes fails to restrict outbound connections or HTTP redirects via iputils.NewSafeDialer(). This allows a malicious or compromised peer to direct the Scheduler to make unauthorized HTTP GET requests to arbitrary internal or external network locations, bypassing network isolation boundaries and exposing internal services.

Details

The vulnerability resides within the DownloadTinyFile function in scheduler/resource/standard/peer.go. This function handles direct HTTP downloads of SizeScope_TINY file payloads from announced peers.

// scheduler/resource/standard/peer.go

func (p *Peer) DownloadTinyFile() ([]byte, error) {
	// ...
	client := &http.Client{Timeout: 10 * time.Second}
	req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, url, nil)
	// ...
	resp, err := client.Do(req)
	// ...
}

The underlying issue is that the http.Client is instantiated directly without a custom DialContext enforcement mechanism (such as the iputils.NewSafeDialer() which exists elsewhere in the Dragonfly2 codebase to prevent SSRF). Consequently, the default Golang http.Client behavior transparently follows HTTP 301/302 redirects. An attacker can announce a task via the gRPC AnnounceTask endpoint, register a peer pointing to an attacker-controlled HTTP server, and have that server issue an HTTP 302 redirect pointing to an internal target (e.g., http://127.0.0.1:8222/ or 169.254.169.254). The Scheduler will follow the redirect, retrieve the internal data, and return it to the attacker when they invoke RegisterPeerTask.

PoC

Prerequisites

  • The Dragonfly2 Manager and Scheduler services must be running.
  • The attacker must be able to communicate with the Scheduler's gRPC port (default 8002).

Reproduction Steps

IMPORTANT: The required PoC scripts have been uploaded as secret GitHub Gists. Ensure you have the docker-compose.yml to reproduce the network environment accurately.

  1. Download the vulnerable environment definition from: docker-compose.yml
  2. Start the Dragonfly2 environment:
    docker compose up -d
  3. Download the exploit script from: poc_exploit.go
  4. Execute the exploit against the Scheduler's gRPC interface (ensure the Docker gateway IP is correctly set if running from the host):
    go run poc_exploit.go
  5. The exploit will output the successful exfiltration of the mocked internal API secret: SECRET123.

(Optional) A control script demonstrating normal download flow without SSRF redirection is available at control-normal_behavior.go.

Log of Evidence

Starting Exploit PoC for SSRF in DownloadTinyFile...
2026/04/18 03:10:15 Redirector Server listening on 192.168.176.1:8111
2026/04/18 03:10:15 Target API listening on 192.168.176.1:8222

[*] Sending AnnounceTask to trigger DownloadTinyFile on Scheduler...
2026/04/18 03:10:17 Redirector received request: GET /download/7b1/7b1b42a40ff754f66d9bb5c311bec0436afca66096763baf12c6c60fed463f9f?peerId=attacker_peer_1_1776481817991475796
2026/04/18 03:10:17 Target API served SECRET123 to 192.168.176.4:46554
[+] AnnounceTask sent successfully.

[*] Sending RegisterPeerTask to exfiltrate DirectPiece...

================= EXPLOIT SUCCESS ==================
Extracted Secret (DirectPiece): SECRET123
====================================================

Impact

This Server-Side Request Forgery (SSRF) allows an unauthenticated attacker to bypass network boundary isolation. The attacker can abuse the Scheduler to scan the internal network, interact with internal APIs (such as Kubernetes APIs, Redis, or cloud metadata instances like 169.254.169.254), and exfiltrate highly sensitive confidential data.

Affected products

  • Ecosystem: go
  • Package name: d7y.io/dragonfly/v2
  • Affected versions: <= 2.4.3
  • Patched versions: None

Severity

  • Severity: High
  • Vector string: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:N

Weaknesses

  • CWE: CWE-918: Server-Side Request Forgery (SSRF)

Occurrences

Permalink Description
https://github.com/dragonflyoss/Dragonfly2/blob/main/scheduler/resource/standard/peer.go#L457-L459 The vulnerable DownloadTinyFile method where a raw http.Client is instantiated and used without SSRF domain/IP protections, allowing malicious redirects to be blindly followed.

Severity

Critical

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Changed
Confidentiality
High
Integrity
Low
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:N

CVE ID

CVE-2026-54709

Weaknesses

Server-Side Request Forgery (SSRF)

The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination. Learn more on MITRE.

Credits