Dagu SSE Authentication Bypass in Basic Auth Mode
Description
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.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
CVE-2026-31882: Unauthenticated access to Dagu SSE endpoints when HTTP Basic auth is enabled, leaking real-time workflow data.
Vulnerability
Overview
CVE-2026-31882 is an authentication bypass vulnerability in Dagu, a workflow engine with a built-in web UI. When Dagu is configured with HTTP Basic authentication (DAGU_AUTH_MODE=basic), all Server-Sent Events (SSE) endpoints are accessible without any credentials. This occurs because the buildStreamAuthOptions() function in internal/service/frontend/server.go returns an auth.Options struct with BasicAuthEnabled: true but AuthRequired defaults to false (Go zero value). The authentication middleware in internal/service/frontend/auth/middleware.go then allows unauthenticated requests when AuthRequired is false, effectively bypassing the authentication that protects the REST API [2][3].
Exploitation and
Attack Surface
An unauthenticated attacker with network access to the Dagu web interface can directly access SSE endpoints such as /api/v1/events/dags, /api/v1/events/dags/{fileName}, /api/v1/events/dags/{fileName}/dag-runs, and /api/v1/events/queues. These endpoints stream real-time data, including DAG names, descriptions, file paths, schedules, tags, execution status, workflow configuration details, execution history, and queue status. No authentication or prerequisites are required beyond network access to the vulnerable service [3].
Impact
Successful exploitation allows an unauthenticated attacker to monitor all workflow activity in real time, gaining visibility into sensitive operational data, workflow logic, and execution logs. This information could be used to understand internal processes, identify potential targets for further attacks, or exfiltrate confidential data. The CVSS 3.1 base score is 7.5 (HIGH), with the vector AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N, indicating high confidentiality impact with no impact on integrity or availability [3].
Mitigation
The vulnerability is fixed in Dagu version 2.2.4. The fix, implemented in commit 064616c9b80c04824c1c7c357308f77f3f24d775, modifies buildStreamAuthOptions() to require credentials for SSE endpoints when basic auth mode is active, aligning the authentication behavior with the REST API [4]. Users should upgrade to version 2.2.4 or later. No workarounds are documented; however, restricting network access to the Dagu web interface can reduce exposure.
AI Insight generated on May 18, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
dagunpm | < 2.2.4 | 2.2.4 |
Affected products
2Patches
1064616c9b80cfix: require basic auth credentials for SSE endpoints (#1752)
2 files changed · +36 −7
internal/service/frontend/api/v1/auth_test.go+31 −0 modified@@ -117,6 +117,37 @@ func TestAuth_Combinations(t *testing.T) { } } +// TestAuth_BasicAuth_SSE_Requires_Credentials verifies that SSE endpoints +// require basic auth when auth.mode is "basic" (regression test for auth bypass). +func TestAuth_BasicAuth_SSE_Requires_Credentials(t *testing.T) { + t.Parallel() + + server := test.SetupServer(t, test.WithConfigMutator(func(cfg *config.Config) { + cfg.Server.Auth.Mode = config.AuthModeBasic + cfg.Server.Auth.Basic.Username = "admin" + cfg.Server.Auth.Basic.Password = "secret" + })) + + sseEndpoints := []string{ + "/api/v1/events/dags", + "/api/v1/events/dag-runs", + "/api/v1/events/queues", + } + + for _, endpoint := range sseEndpoints { + t.Run(endpoint, func(t *testing.T) { + // No credentials — must be rejected (not bypassed) + server.Client().Get(endpoint). + ExpectStatus(http.StatusUnauthorized).Send(t) + + // Wrong credentials — must be rejected + server.Client().Get(endpoint). + WithBasicAuth("wrong", "wrong"). + ExpectStatus(http.StatusUnauthorized).Send(t) + }) + } +} + func TestAuth_BuiltinMode(t *testing.T) { t.Parallel()
internal/service/frontend/server.go+5 −7 modified@@ -1194,17 +1194,15 @@ func (srv *Server) buildStreamAuthOptions(realm string) auth.Options { return auth.Options{Realm: realm} } - // Basic auth mode: The browser EventSource API cannot send custom headers, - // so it cannot provide Basic credentials. We enable Basic auth validation - // (so programmatic clients like curl are authenticated) but set - // AuthRequired=false so browser SSE connections without credentials are - // not blocked with 401. - // FIXME: add a session-token mechanism for basic-auth users so browser - // EventSource requests can authenticate via the ?token= query parameter. + // Basic auth mode: require credentials for SSE endpoints just like REST. + // Browsers handle 401 + WWW-Authenticate: Basic challenges natively, + // caching credentials per origin/realm, so EventSource requests will + // include Basic auth automatically after the user authenticates once. if authCfg.Mode == config.AuthModeBasic { return auth.Options{ Realm: realm, BasicAuthEnabled: true, + AuthRequired: true, Creds: map[string]string{authCfg.Basic.Username: authCfg.Basic.Password}, } }
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-9wmw-9wph-2vwpghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-31882ghsaADVISORY
- github.com/dagu-org/dagu/commit/064616c9b80c04824c1c7c357308f77f3f24d775ghsax_refsource_MISCWEB
- github.com/dagu-org/dagu/pull/1752ghsax_refsource_MISCWEB
- github.com/dagu-org/dagu/releases/tag/v2.2.4ghsax_refsource_MISCWEB
- github.com/dagu-org/dagu/security/advisories/GHSA-9wmw-9wph-2vwpghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.