Skip to content

Commit 064616c

Browse files
authored
fix: require basic auth credentials for SSE endpoints (#1752)
1 parent d6d3b8a commit 064616c

File tree

2 files changed

+36
-7
lines changed

2 files changed

+36
-7
lines changed

internal/service/frontend/api/v1/auth_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,37 @@ func TestAuth_Combinations(t *testing.T) {
117117
}
118118
}
119119

120+
// TestAuth_BasicAuth_SSE_Requires_Credentials verifies that SSE endpoints
121+
// require basic auth when auth.mode is "basic" (regression test for auth bypass).
122+
func TestAuth_BasicAuth_SSE_Requires_Credentials(t *testing.T) {
123+
t.Parallel()
124+
125+
server := test.SetupServer(t, test.WithConfigMutator(func(cfg *config.Config) {
126+
cfg.Server.Auth.Mode = config.AuthModeBasic
127+
cfg.Server.Auth.Basic.Username = "admin"
128+
cfg.Server.Auth.Basic.Password = "secret"
129+
}))
130+
131+
sseEndpoints := []string{
132+
"/api/v1/events/dags",
133+
"/api/v1/events/dag-runs",
134+
"/api/v1/events/queues",
135+
}
136+
137+
for _, endpoint := range sseEndpoints {
138+
t.Run(endpoint, func(t *testing.T) {
139+
// No credentials — must be rejected (not bypassed)
140+
server.Client().Get(endpoint).
141+
ExpectStatus(http.StatusUnauthorized).Send(t)
142+
143+
// Wrong credentials — must be rejected
144+
server.Client().Get(endpoint).
145+
WithBasicAuth("wrong", "wrong").
146+
ExpectStatus(http.StatusUnauthorized).Send(t)
147+
})
148+
}
149+
}
150+
120151
func TestAuth_BuiltinMode(t *testing.T) {
121152
t.Parallel()
122153

internal/service/frontend/server.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,17 +1194,15 @@ func (srv *Server) buildStreamAuthOptions(realm string) auth.Options {
11941194
return auth.Options{Realm: realm}
11951195
}
11961196

1197-
// Basic auth mode: The browser EventSource API cannot send custom headers,
1198-
// so it cannot provide Basic credentials. We enable Basic auth validation
1199-
// (so programmatic clients like curl are authenticated) but set
1200-
// AuthRequired=false so browser SSE connections without credentials are
1201-
// not blocked with 401.
1202-
// FIXME: add a session-token mechanism for basic-auth users so browser
1203-
// EventSource requests can authenticate via the ?token= query parameter.
1197+
// Basic auth mode: require credentials for SSE endpoints just like REST.
1198+
// Browsers handle 401 + WWW-Authenticate: Basic challenges natively,
1199+
// caching credentials per origin/realm, so EventSource requests will
1200+
// include Basic auth automatically after the user authenticates once.
12041201
if authCfg.Mode == config.AuthModeBasic {
12051202
return auth.Options{
12061203
Realm: realm,
12071204
BasicAuthEnabled: true,
1205+
AuthRequired: true,
12081206
Creds: map[string]string{authCfg.Basic.Username: authCfg.Basic.Password},
12091207
}
12101208
}

0 commit comments

Comments
 (0)