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

Fix Unsafe inline scripts by adding nonce as CSP #3832

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

tabraiz12
Copy link
Collaborator

What changes were proposed in this pull request?

  • Added a middleware to add request.nonce and include it in the request script
  • Added unsafe-eval in CSP for temporarily handling the ko bindings, this fix will be part of another PR.

How was this patch tested?

  • Manual Test
  • Testes Login
  • Tested Editor and running few commands
  • Navigated to job browser and admin pages didn't find any js issues.
  • Removed the nonce attribute and verified that its throwing error without those.

Please review Hue Contributing Guide before opening a pull request.

response = self.get_response(request)
csp_policy = "script-src 'nonce-{}' 'strict-dynamic' 'unsafe-eval';".format(nonce)

response['Content-Security-Policy'] = csp_policy
Copy link
Contributor

Choose a reason for hiding this comment

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

This one is configurable in the .ini, secure_content_security_policy, I believe you need to merge it somehow here instead. You could potentially just string replace 'nonce' with 'nonce-{}'...

Copy link
Contributor

Choose a reason for hiding this comment

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

And add 'strict-dynamic' to the default of the config value.

Copy link
Contributor

Choose a reason for hiding this comment

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

Note that there's already a def ContentSecurityPolicyMiddleware in the same file..

Copy link
Collaborator

@bjornalm bjornalm left a comment

Choose a reason for hiding this comment

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

This is great stuff!
Really happy this is working :-)

Approved but take a look at Johan's comments about where to add/remove the csp_policy keywords.

@@ -267,7 +267,7 @@ else:

<div class="clipboard-content"></div>

<script type="text/javascript">
<script nonce="${request.csp_nonce if request else csp_nonce}" type="text/javascript">
Copy link
Collaborator

Choose a reason for hiding this comment

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

why the 2 different options?

Copy link
Collaborator

@Harshg999 Harshg999 left a comment

Choose a reason for hiding this comment

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

I've added few review comments. Can you please also add unit tests?

desktop/core/src/desktop/conf.py Show resolved Hide resolved

CSP_NONCE = Config(
key="csp_nonce",
help=_('CSP NONCE can be true or false'),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Need to improve help message

desktop/core/src/desktop/lib/django_util.py Show resolved Hide resolved
@@ -69,6 +70,83 @@
from libsaml.conf import CDP_LOGOUT_URL
from urllib.parse import urlparse

import base64
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: Importing twice? Check line 21

import os

# Number of random bytes in the nonce:
NONCE_BYTES = 24
Copy link
Collaborator

Choose a reason for hiding this comment

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

Any specific reason for setting this as 24?

request.csp_nonce = nonce

def process_response(self, request, response):
# Add the secure CSP if it doesn't exist
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is the comment correct here?

Comment on lines +994 to +995
if not CSP_NONCE.get():
return response
Copy link
Collaborator

Choose a reason for hiding this comment

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

If let's say this condition is True, then it will return but isn't this regressing from the old change where it was setting Content-Security-Policy header in response and then returning?

Comment on lines 1004 to 1005
nonce_found, has_nonce = nonce_exists(response)
if has_nonce:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we really need 2 return values here?

@@ -502,3 +502,13 @@ def __init__(self, data, encoder=DjangoJSONEncoder, safe=True,
kwargs.setdefault('content_type', 'application/json')
data = json.dumps(data, cls=encoder, **json_dumps_params)
super(JsonResponse, self).__init__(content=data, **kwargs)


def nonce_attribute(context):
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is context here?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Why are these changes present in this file?

Copy link

This PR is stale because it has been open 45 days with no activity and is not labeled "Prevent stale". Remove "stale" label or comment or this will be closed in 10 days.

@github-actions github-actions bot added the Stale label Nov 15, 2024
@bjornalm bjornalm removed the Stale label Nov 15, 2024
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.

4 participants