Sensor API answers other origins (token only); external demo page

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Mitchell-Johnson
2026-09-19 08:49:59 -07:00
co-authored by Claude Fable 5.1
parent 0b0b2897cb
commit 65a9888784
4 changed files with 229 additions and 0 deletions
+26
View File
@@ -186,6 +186,19 @@ func New(cfg *config.Config, sessions *auth.Sessions, mgr *term.Manager, col *me
return s
}
// sensorPath reports whether a path belongs to the read-only sensor API.
func sensorPath(p string) bool {
if p == "/metrics" || p == "/api/sensors" || strings.HasPrefix(p, "/api/sensors/") || strings.HasPrefix(p, "/api/fleet/sensors/") {
return true
}
if rest, ok := strings.CutPrefix(p, "/api/nodes/"); ok {
if _, after, ok := strings.Cut(rest, "/"); ok {
return after == "sensors" || strings.HasPrefix(after, "sensors/")
}
}
return false
}
// Handler wraps the mux with headers a root-capable console should always send.
func (s *Server) Handler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -197,6 +210,19 @@ func (s *Server) Handler() http.Handler {
h.Set("Content-Security-Policy", "frame-ancestors 'none'")
}
h.Set("X-Content-Type-Options", "nosniff")
// The sensor API is for other people's pages too. Any origin may read it — with a
// token, never the session: "*" is the one value browsers refuse to pair with
// cookies, so a foreign page can't ride a logged-in console. Nothing else is opened.
if sensorPath(r.URL.Path) {
h.Set("Access-Control-Allow-Origin", "*")
if r.Method == http.MethodOptions {
h.Set("Access-Control-Allow-Methods", "GET, POST")
h.Set("Access-Control-Allow-Headers", "Authorization, Content-Type")
h.Set("Access-Control-Max-Age", "86400")
w.WriteHeader(http.StatusNoContent)
return
}
}
h.Set("Referrer-Policy", "no-referrer")
s.mux.ServeHTTP(w, r)
})