Dagu: Path Traversal via `dagRunId` in Inline DAG Execution
Date: 2026-03
Affected: go/github.com/dagu-org/dagu
Attack vector: path-traversal
Category: vulnerability-disclosure
Severity: Critical
CVE: CVE-2026-31886
CWE: CWE-22
CVSS: 9.1 (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:H)

## 1. Vulnerability Summary The `dagRunId` request field accepted by the inline DAG execution endpoints is passed directly into `filepath.Join` to construct a temporary directory path without any format validation. Go's `filepath.Join` resolves `..` segments lexically, so a caller can supply a value such as `".."` to redirect the computed directory outside the intended `/tmp/<name>/<id>` path. A deferred cleanup function that calls `os.RemoveAll` on that directory then runs unconditionally when the HTTP handler returns, deleting whatever directory the traversal resolved to. With `dagRunId` set to `".."`, the resolved directory is the system temporary directory (`/tmp` on Linux). On non-root deployments, `os.RemoveAll("/tmp")` removes all files in `/tmp` owned by the dagu process user, disrupting every concurrent dagu run that has live temp files. On root or Docker deployments, the call removes the entire contents of `/tmp`, causing a system-wide denial of service. ## 2. This Is Not a Duplicate of Existing Advisories Two security advisories are already published for dagu. This vulnerability is distinct from both. **GHSA-6qr9-g2xw-cw92** fixed the fact that the default authentication mode was `none`, allowing unauthenticated access to the inline execution endpoint. That advisory covers authentication bypass. The `dagRunId` path traversal described here is a separate input-validation flaw in `loadInlineDAG()` that exists regardless of whether authentication is required and


Mitigations:

Architectural layers (MAESTRO):