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

Replacing X-Frame-Options HTTP header with CSP #402

Merged
merged 13 commits into from
Jan 17, 2025
Merged

Conversation

fyvon
Copy link
Member

@fyvon fyvon commented Jan 13, 2025

The HTTP header X-Frame-Options "Deny" would not allow the PGS Catalog to be displayed in an iframe on the EBI training website. There is supposed to be the option "allow-from https://..." but it is not supported by mordern browsers anymore. The solution was either removing this security header, or to update it with Content Security Policies (CSP) header.

CSP use the directive "frame-ancestors" to allow specific websites to show a page into iframes.
The consequence though was the need to specify all trusted external resources that we use (js and css) to allow the browser to load them, in an iframe or not, because of CSP strictness. One problem was with the external resources imported from other resources, which need to be allowed too. To avoid this issue, I chose to use a "nonce" for javascript imports along with the 'strict-dynamic' option. Script HTML elements with the nonce are considered trusted and with 'strict-dynamic' can load any other resource they need. It could only work with scripts though, each style source (css) still need to be specified in the header, which didnt cause too much trouble. To avoid the tedious task to add the nonce in all <script> elements in the templates, I added a middleware class to do it automatically. The rest of the CSP implementation is done with django-csp.

The current policies were tested with https://csp-evaluator.withgoogle.com/ and considered good.

fyvon added 8 commits January 10, 2025 15:08
This was necessary to make CSP policies happy. The current directives don't allow inline code such as "onclick" if nonce is used.
Simplest solution to toolbar.js being blocked by CSP
@fyvon fyvon requested a review from ens-lgil January 13, 2025 12:13
pgs_web/settings.py Outdated Show resolved Hide resolved
CSP_STYLE_SRC = ("'self'",
"'unsafe-inline'",
"https://cdn.jsdelivr.net/",
"https://use.fontawesome.com/",
Copy link
Member

Choose a reason for hiding this comment

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

Wondering if we should store the following URLs into variables as they appear mor than once:

Copy link
Member Author

Choose a reason for hiding this comment

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

I will think about it, to me it would make the code less clear. Or on the other extreme we could also use variables for those in css.html and js.html

Copy link
Member

Choose a reason for hiding this comment

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

Yes, the final goal would be to store all the URLs in variables, so we will need to change the URLs in one place only.
We have some here: https://github.com/PGScatalog/PGS_Catalog/blob/master/pgs_web/constants.py#L51

@fyvon fyvon requested a review from ens-lgil January 16, 2025 14:36
@fyvon fyvon merged commit a951d15 into master Jan 17, 2025
@fyvon fyvon deleted the improve/implement_csp branch January 17, 2025 13:17
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.

2 participants