You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: cmd/lwauth-controlplane/main.go
+9Lines changed: 9 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -90,6 +90,15 @@ func main() {
90
90
streamHub:=streaming.NewHub(registry, aggregator)
91
91
streamHub.AllowedOrigin=cfg.ConsoleOrigin
92
92
93
+
// SECURITY: When auth is enabled, require a console origin to be
94
+
// set so WebSocket upgraders fail-closed on cross-origin connections.
95
+
// If the operator forgot to set CP_CONSOLE_ORIGIN, warn loudly and
96
+
// use the request's Host header as the default (same-origin only).
97
+
effectiveOrigin:=cfg.ConsoleOrigin
98
+
ifcfg.AuthEnabled&&effectiveOrigin=="" {
99
+
logger.Error(nil, "CP_AUTH_ENABLED=true but CP_CONSOLE_ORIGIN is empty — WebSocket connections will accept any origin. Set CP_CONSOLE_ORIGIN to the console URL (e.g. https://lwauth.example.com).")
100
+
}
101
+
93
102
// Alerting engine (Phase 2). Pulls rule evaluations from
94
103
// Prometheus and Loki when configured; degrades to a readonly
95
104
// catalog with running rule definitions but no firings when the
Copy file name to clipboardExpand all lines: internal/controlplane/api/endpoints_alerts.go
+31-1Lines changed: 31 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -160,7 +160,18 @@ func (s *Server) handlePutRules(w http.ResponseWriter, r *http.Request) {
160
160
return
161
161
}
162
162
// Validate the override set before persisting: each rule must have
163
-
// a unique name and a sane (positive) For/Window when Enabled.
163
+
// a unique name. The Query and Source fields are rejected —
164
+
// operators can only override Threshold, For, Window, Enabled,
165
+
// and Severity on existing built-in rules. This prevents
166
+
// PromQL/LogQL injection via the API: the built-in catalog's
167
+
// queries are operator-reviewed at compile time and cannot be
168
+
// replaced at runtime.
169
+
knownRules:=map[string]bool{}
170
+
ifs.AlertEngine!=nil {
171
+
for_, r:=ranges.AlertEngine.Rules() {
172
+
knownRules[r.Name] =true
173
+
}
174
+
}
164
175
seen:=map[string]bool{}
165
176
fori, r:=rangereq.Overrides {
166
177
ifr.Name=="" {
@@ -172,6 +183,25 @@ func (s *Server) handlePutRules(w http.ResponseWriter, r *http.Request) {
172
183
return
173
184
}
174
185
seen[r.Name] =true
186
+
// Reject custom rules (name not in the built-in catalog) —
187
+
// only overrides of existing defaults are allowed via the
188
+
// API. New custom rules must be added to the ConfigMap
189
+
// directly by the operator.
190
+
if!knownRules[r.Name] {
191
+
writeError(w, http.StatusBadRequest, "override["+strconv.Itoa(i)+"]: unknown rule name "+strconv.Quote(r.Name)+" — only overrides of built-in rules are allowed via the API")
192
+
return
193
+
}
194
+
// Reject Query and Source overrides — these are the
195
+
// PromQL/LogQL injection vectors. Operators who need to
196
+
// change a query must edit the ConfigMap directly.
197
+
ifr.Query!="" {
198
+
writeError(w, http.StatusBadRequest, "override["+strconv.Itoa(i)+"]: query field cannot be set via the API — edit the ConfigMap directly")
199
+
return
200
+
}
201
+
ifr.Source!="" {
202
+
writeError(w, http.StatusBadRequest, "override["+strconv.Itoa(i)+"]: source field cannot be set via the API — edit the ConfigMap directly")
0 commit comments