Skip to content

[MINOR] Tighten origin and content-type handling in REST/WebSocket layer#5229

Draft
jongyoul wants to merge 1 commit intoapache:masterfrom
jongyoul:minor-cors-hardening
Draft

[MINOR] Tighten origin and content-type handling in REST/WebSocket layer#5229
jongyoul wants to merge 1 commit intoapache:masterfrom
jongyoul:minor-cors-hardening

Conversation

@jongyoul
Copy link
Copy Markdown
Member

@jongyoul jongyoul commented May 6, 2026

What is this PR for?

Apply stricter defaults to the request-handling layer for tighter out-of-the-box behavior:

  • CorsFilter blocks state-changing methods (POST/PUT/DELETE/PATCH) and cross-origin preflight requests when the Origin header is not in the configured allow-list. Access-Control-Allow-Credentials is only sent when the Origin is allowed.
  • The default value of zeppelin.server.allowed.origins changes from * to empty so cross-origin browser access must be explicitly enabled. Operators relying on the previous default need to set this back to * or to specific origin(s). Same-origin / same-host and non-browser clients are unaffected.
  • A new Jersey request filter restricts REST request bodies on state-changing methods to application/json, application/x-www-form-urlencoded, or multipart/form-data; other media types are rejected with 415.
  • The default shiro.ini.template now sets cookie.sameSite = LAX.
  • ZeppelinClient.addParagraph and updateParagraph now send an explicit Content-Type: application/json header so they pass the new filter.
  • CorsUtils.isValidOrigin normalizes the Origin header to lowercase before the allow-list membership check, mirroring how the configured origins are stored, so case differences in the Origin header do not produce false rejections.
  • A small HttpMethods utility holds the shared STATE_CHANGING method set used by both the servlet filter and the Jersey filter.

What type of PR is it?

Improvement

Todos

  • CI green

Questions

  • None

Screenshots (if appropriate)

N/A

Apply stricter defaults to the request-handling layer:

- CorsFilter blocks state-changing methods (POST/PUT/DELETE/PATCH) and
  cross-origin preflight requests when the Origin header is not in the
  configured allow-list. Access-Control-Allow-Credentials is only sent
  when the Origin is allowed.
- The default value of zeppelin.server.allowed.origins changes from "*"
  to empty so cross-origin browser access must be explicitly enabled.
  Operators relying on the previous default need to set this back to "*"
  or to specific origin(s). Same-origin/same-host and non-browser
  clients are unaffected.
- A new request filter restricts REST request bodies on state-changing
  methods to application/json, application/x-www-form-urlencoded, or
  multipart/form-data; other media types are rejected with 415.
- The default shiro.ini.template now sets cookie.sameSite = LAX.
- ZeppelinClient.addParagraph and updateParagraph now send an explicit
  Content-Type: application/json header so they pass the new filter.
- CorsUtils.isValidOrigin normalizes the Origin header to lowercase
  before the allow-list membership check, mirroring how the configured
  origins are stored, so case differences in the Origin header do not
  produce false rejections.
- A small HttpMethods utility holds the shared STATE_CHANGING method
  set used by both the servlet filter and the Jersey filter.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant