fix: harden CSRF protections - #6186
Conversation
There was a problem hiding this comment.
Pull request overview
This pull request hardens Chronograf’s CSRF posture and adds additional browser isolation measures by introducing server-side request guards (Origin/Referer validation for session-auth unsafe methods, and required X-Requested-With on sensitive endpoints) and updating UI/Cypress clients to comply.
Changes:
- Add server middleware for same-origin enforcement (session-cookie + unsafe methods), required
X-Requested-With: XMLHttpRequeston query/proxy endpoints, and default security headers. - Update UI worker/fetch/XHR callers to send
X-Requested-With, and update Cypresscy.requestto inject Origin/Referer for unsafe same-origin API calls. - Tighten session cookie attributes (SameSite=Strict and conditional Secure) and remove Data Explorer query param syncing logic.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/src/worker/jobs/proxy.ts | Adds X-Requested-With to proxy POST fetches. |
| ui/src/worker/jobs/postJSON.ts | Adds X-Requested-With to JSON POST fetches. |
| ui/src/utils/ajax.ts | Injects X-Requested-With into non-GET requests and /proxy/flux GET. |
| ui/src/shared/apis/flux/query.ts | Adds X-Requested-With to Flux XHR execution. |
| ui/src/shared/apis/flux/cancellableQuery.ts | Adds X-Requested-With to Flux cancellable fetch. |
| ui/src/data_explorer/containers/DataExplorer.tsx | Removes URL query/script param read/write behavior. |
| ui/cypress/support/commands.ts | Overwrites cy.request to inject Origin/Referer for unsafe same-origin calls. |
| ui/cypress/integration/explore_influxql.test.ts | Makes the test resilient to non-deterministic DB names from templates. |
| server/server.go | Passes TLS-derived “secure cookie” flag into cookie JWT auth. |
| server/security_headers.go | Adds middleware to set XFO + CORP headers. |
| server/same_origin.go | Adds middleware to require same-origin Origin/Referer for unsafe session-cookie requests. |
| server/requested_with.go | Adds middleware requiring X-Requested-With: XMLHttpRequest. |
| server/mux.go | Wires new middleware into mux and protects query/proxy endpoints. |
| server/middle_test.go | Adds tests for the new middleware behaviors. |
| oauth2/cookies.go | Adds SameSite=Strict + Secure support to session cookies. |
| oauth2/cookies_test.go | Updates tests for new NewCookieJWT signature. |
| CHANGELOG.md | Documents the security hardening under Unreleased. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR hardens Chronograf’s browser-facing security posture by adding CSRF defenses on unsafe endpoints, tightening session-cookie attributes, and updating UI/Cypress callers to send the required request headers.
Changes:
- Enforce
X-Requested-With: XMLHttpRequeston selected query/proxy endpoints and add a same-origin check for unsafe methods when session cookies are present. - Add defense-in-depth security response headers and strengthen session cookie attributes (
SameSite, optionalSecure). - Update UI worker/Flux clients and Cypress tests to include
X-Requested-With(and injectOrigin/Refererin Cypress), plus adjust a flaky InfluxQL e2e assertion.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/src/worker/jobs/proxy.ts | Adds X-Requested-With (+ JSON content type) to proxy worker POSTs. |
| ui/src/worker/jobs/postJSON.ts | Adds X-Requested-With to JSON POST worker requests. |
| ui/src/utils/ajax.ts | Injects X-Requested-With for non-GET and /proxy/flux GET requests. |
| ui/src/shared/apis/flux/query.ts | Adds X-Requested-With header to Flux XHR POST. |
| ui/src/shared/apis/flux/cancellableQuery.ts | Adds X-Requested-With to cancellable Flux fetch headers. |
| ui/src/data_explorer/containers/DataExplorer.tsx | Removes query-param read/write logic (and related imports). |
| ui/cypress/support/commands.ts | Overwrites cy.request to inject Origin/Referer for same-origin unsafe methods. |
| ui/cypress/integration/explore_influxql.test.ts | Makes metaquery template test resilient by extracting created DB name dynamically. |
| server/server.go | Passes a new secure flag into cookie auth creation. |
| server/security_headers.go | Adds middleware to set X-Frame-Options and Cross-Origin-Resource-Policy. |
| server/same_origin.go | Adds middleware to block cross-origin unsafe requests when session cookie is present. |
| server/requested_with.go | Adds middleware to require X-Requested-With: XMLHttpRequest. |
| server/mux.go | Applies new guards to proxy/queries routes and wires global security middleware. |
| server/middle_test.go | Adds unit tests for the new middleware behaviors. |
| oauth2/cookies.go | Adds Secure + SameSite=Strict to session cookies and updates constructor signature. |
| oauth2/cookies_test.go | Updates tests for the new cookie constructor signature. |
| CHANGELOG.md | Notes the security hardening under “Unreleased”. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
I've gone through the check list of tests in the description and repeated them against a local build of this branch built in a cross builder container. So this is more or less what will be built in CI. Note there is currently an issue with nightly builds in CI due to missing compilers for darwin. The local build was for linux amd64 only. An application was created in my Github account to use OAuth2 configuration. screenshot of initial oauth2 configuration This configuration is for the plain HTTP envoy proxy at localhost:10000
Everything appears to work as could be expected... Verification test run notes
With Github OAuth2 - OK
With Github OAuth2 - OK session cookie cleared on logout, new session cookie on login first session cookie... second session cookie...
With Github OAuth2 - OK
query? parameter does not load - OK
Rendered - OK
Rendered - OK
POST - OK
None encountered - OK
With HTTP Envoy proxy - OK
None detected - OK |
karel-rehor
left a comment
There was a problem hiding this comment.
Review in progress. One question on unit tests.
karel-rehor
left a comment
There was a problem hiding this comment.
Looks good to me 🚴 🏁

CSRF hardening fixes:
?query=/?script=) on page load. This directly addresses the issue recommendation to disable URL-based query execution (or at least stop auto-execution). It removes the crafted-link CSRF vector described in CSA-H-04.SameSite=Strict) and secure transport settings where appropriate. This reduces the chance that browser session cookies are sent on cross-origin requests.X-Requested-With: XMLHttpRequest. This follows the issue proposal to require an AJAX-only header so cross-origin pages cannot trigger those requests directly. Requests without that header are rejected.Fixes beyond CSA-H-04 recommendations:
X-Frame-Options: SAMEORIGINandCross-Origin-Resource-Policy: same-originare now set. This reduces framing and cross-origin resource abuse opportunities.Tests to do