Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to disable X-Frame-Options header? #103

Open
erral opened this issue Jun 6, 2023 · 9 comments · May be fixed by #122
Open

How to disable X-Frame-Options header? #103

erral opened this issue Jun 6, 2023 · 9 comments · May be fixed by #122

Comments

@erral
Copy link
Member

erral commented Jun 6, 2023

How can I completely disable (for the whole site or a given view) the X-Frame-Options header added by this product?

Specifically I need to be able to embed in an iframe a page rendered by Plone. The current best practice seems to remove the X-Frame-Options header (apart from using CSP), but the current environment-variable approach doesn't allow to remove it, I can only set it to empty, or None, which does not work according to MDN: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options

I have added a workaround in nginx adding the following sentence:

proxy_hide_header X-Frame-Options;

But it would be desirable to be able to remove it in a more flexible way for the whole site or view-per-view.

@Rudd-O
Copy link

Rudd-O commented Jun 6, 2023

@Rudd-O Rudd-O closed this as completed Jun 6, 2023
@yurj
Copy link

yurj commented Jun 6, 2023

In Apache I do:
Header set Content-Security-Policy "frame-ancestors 'self' *.domainsthatcanuseiframe;"

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors

I think you can just use * and set it in the view you want to be possible to embed in an iframe.

@erral
Copy link
Member Author

erral commented Jun 6, 2023

https://github.com/plone/plone.protect/blob/8b8b36a570354e543b8a3fbe3696dd9ac69c4ad3/README.rst#clickjacking-protection I hope this answers your question.

No, this doesn't answer my question.

Because the actual code sets always or never the header, it is not possible to override it to remove it from a given view.

@erral erral reopened this Jun 6, 2023
@Rudd-O
Copy link

Rudd-O commented Jun 6, 2023

@erral oh that's bad. Let's keep this open for the fix.

@Rudd-O
Copy link

Rudd-O commented Jun 6, 2023

I think it's dumb to use env vars for this, as one may want to govern the behavior per site or even per page.

@devdanzin
Copy link
Member

Would something like the following (but tested and better written, of course) work?

# Env var set to empty or None, no header from view: remove the header
if X_FRAME_OPTIONS in ("", "None") and not self.request.response.getHeader("X-Frame-Options"):
    self.request.response.headers.pop("x-frame-options", None)
# View/site intends header to be empty: remove header 
elif self.request.response.getHeader("X-Frame-Options") in ("", "None", None):
    self.request.response.headers.pop("x-frame-options", None)
# Header not present, env var set: set header
elif X_FRAME_OPTIONS not in ("", "None") and self.request.response.getHeader("X-Frame-Options") is None:
    self.request.response.setHeader("X-Frame-Options", X_FRAME_OPTIONS)
# Header present, leave it be
else:
    assert self.request.response.getHeader("X-Frame-Options")

This would mean a set X-Frame-Options would be kept, any attempt at making it empty would remove the header, but if the header is not present then use the env var to set it. If it makes any sense, I can work on a PR.

@davisagli
Copy link
Member

@erral @devdanzin The existing code only adds the response header if X_FRAME_OPTIONS (which comes from os.environ.get("PLONE_X_FRAME_OPTIONS", "SAMEORIGIN")) evaluates to boolean true -- so I think it should already be possible to disable it by setting PLONE_X_FRAME_OPTIONS to an empty string.

I would be inclined to simply document that and not add the complexity of a way to disable it for specific views, since https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options says this is no longer the recommended way to prevent embedding.

@devdanzin We spoke briefly in Brasilia. Thanks for submitting this, and sorry for not reviewing it sooner.

@Rudd-O
Copy link

Rudd-O commented Dec 18, 2024

With the PR queued up to fix this, I think this will soon be closed.

@erral
Copy link
Member Author

erral commented Dec 18, 2024

@erral @devdanzin The existing code only adds the response header if X_FRAME_OPTIONS (which comes from os.environ.get("PLONE_X_FRAME_OPTIONS", "SAMEORIGIN")) evaluates to boolean true -- so I think it should already be possible to disable it by setting PLONE_X_FRAME_OPTIONS to an empty string.

The point is that the environment variable either removes the header completely or sets it for all URLs, and we can't override it on per-view basis. That was my initial intention.

Anyway, if the X-Frame-Options header is no longer the way to go, and now a CSP should be configured, that's fine for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants