Skip to content

feat: set X-Frame-Options header by default#24525

Open
totally-not-ai[bot] wants to merge 3 commits into
mainfrom
feat/default-x-frame-options
Open

feat: set X-Frame-Options header by default#24525
totally-not-ai[bot] wants to merge 3 commits into
mainfrom
feat/default-x-frame-options

Conversation

@totally-not-ai

@totally-not-ai totally-not-ai Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Send the X-Frame-Options HTTP response header with a default value of
SAMEORIGIN for the application page so browsers opt in to clickjacking
protection out of the box. The value is configurable through the new
frameOptions init parameter (DeploymentConfiguration#getFrameOptions);
an empty value disables the header for applications meant to be embedded
in a frame.

Fixes #23415

@cla-assistant

cla-assistant Bot commented Jun 4, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.


String frameOptions = config.getFrameOptions();
if (frameOptions != null && !frameOptions.isEmpty()) {
response.setHeader("X-Frame-Options", frameOptions);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO this should only be done if no X-Frame-Options are already present

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point — updated so the header is only set when the response doesn't already contain an X-Frame-Options header (via response.containsHeader(...)), letting an app-set or filter-set value take precedence. Added a test covering the already-present case. Thanks!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should log a warning if a non-default setting is ignored due to an existing header

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — when the X-Frame-Options header is already present and an explicit frameOptions value was configured, the handler now logs a warning that the configured value is being ignored (the default, unconfigured case stays silent).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic should go only after service.modifyIndexHtmlResponse(indexHtmlResponse) so that the application has a chance of setting their own custom header before we check if there's already a header.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though on the other hand, the whole point of modifyIndexHtmlResponse is that the application can override whatever the framework has set. So maybe it's still better to have it before modifyIndexHtmlResponse.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed — and that's already how it's placed: the header is set here (before modifyIndexHtmlResponse), so an IndexHtmlRequestListener can still override it via getVaadinResponse().setHeader("X-Frame-Options", ...) (which replaces the framework default). The containsHeader guard only defers to a value set even earlier, e.g. by a servlet filter. So the framework sets a sensible default, the app can override, and an external pre-set header is respected. Happy to move it after modifyIndexHtmlResponse instead if you'd prefer listener-set headers to win over the configured value without a warning — let me know.

@knoobie knoobie Jun 4, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should log a warning if a non-default setting is ignored due to an existing header

While I understand the intention.. this might result in a lot of noise.. some tools do things like "This is logged once at WARN and afterwards at DEBUG" so that the log is not poluted

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The point is that it's logging only if you have set the configuration property and also set a custom header. You get rid of the annoying logging by clearing the configuration property back to the default value.

@github-actions github-actions Bot added the +0.1.0 label Jun 4, 2026

String frameOptions = config.getFrameOptions();
if (frameOptions != null && !frameOptions.isEmpty()) {
response.setHeader("X-Frame-Options", frameOptions);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should log a warning if a non-default setting is ignored due to an existing header


String frameOptions = config.getFrameOptions();
if (frameOptions != null && !frameOptions.isEmpty()) {
response.setHeader("X-Frame-Options", frameOptions);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic should go only after service.modifyIndexHtmlResponse(indexHtmlResponse) so that the application has a chance of setting their own custom header before we check if there's already a header.

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown

Test Results

 1 434 files  ±0   1 434 suites  ±0   1h 23m 57s ⏱️ + 2m 18s
10 096 tests +4  10 028 ✅ +4  68 💤 ±0  0 ❌ ±0 
10 568 runs  +4  10 499 ✅ +4  69 💤 ±0  0 ❌ ±0 

Results for commit 94f5671. ± Comparison against base commit 1e54239.

♻️ This comment has been updated with latest results.

totally-not-ai Bot added 3 commits June 7, 2026 12:13
Send the X-Frame-Options HTTP response header with a default value of
SAMEORIGIN for the application page so browsers opt in to clickjacking
protection out of the box. The value is configurable through the new
frameOptions init parameter (DeploymentConfiguration#getFrameOptions);
an empty value disables the header for applications meant to be embedded
in a frame.

Fixes #23415
@Artur- Artur- force-pushed the feat/default-x-frame-options branch from e52b919 to 94f5671 Compare June 7, 2026 09:14
@Artur- Artur- requested a review from Legioth June 7, 2026 09:14
@sonarqubecloud

sonarqubecloud Bot commented Jun 7, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Set X-Frame-Options by default

2 participants