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

Add support for Content-Security-Policy #391

Closed
prauscher opened this issue Dec 21, 2023 · 3 comments
Closed

Add support for Content-Security-Policy #391

prauscher opened this issue Dec 21, 2023 · 3 comments

Comments

@prauscher
Copy link
Contributor

prauscher commented Dec 21, 2023

SAML with POST-Bindings has inherent problems with Content-Security-Policies being in-place: The three views LoginView, LogoutView and LogoutInitView all need at least form-action https: and probably script-src 'unsafe-inline' to autostart redirection.

Gladly, django-csp exists and allows for quite easy setting of these headers, so if an application activates them, djangosaml2 won't work any longer due to CSP restrictions being enabled. As most users probably do not want to enable unsafe-inline and form-action to any https-site, djangosaml2 should update the values like using
@csp_update(SCRIPT_SRC=["'unsafe-inline'"], FORM_ACTION=["https:"]).

My current implementation as a quickfix is btw:

from csp.deorators import csp_update
from djangosaml2 import views as saml2_views

saml2_csp = csp_update(SCRIPT_SRC=["'unsafe-inline'"], FORM_ACTION=["https:"])

urlpatterns = [
    path("login/", saml2_csp(saml2_views.LoginView.as_view()), name="saml2_login"),
    path("acs/", saml2_views.AssertionConsumerServiceView.as_view(), name="saml2_acs"),
    path("logout/", saml2_cspsaml2_views.LogoutInitView.as_view(), name="saml2_logout"),
    path("ls/", saml2_cspsaml2_views.LogoutView.as_view()), name="saml2_ls"),
    path("ls/post/", saml2_cspsaml2_views.LogoutView.as_view()), name="saml2_ls_post"),
    path("metadata/", saml2_views.MetadataView.as_view(), name="saml2_metadata"),
    ...]

instead of

urlpatterns = [include("djangosaml2.urls"), ...]

If one were to implement this properly, one option would probably be to do something like

try:
    from csp.decorators import csp_update
except ImportError:
    def saml2_csp(func):
        return func
else:
    saml2_csp = csp_update(SCRIPT_SRC=["'unsafe-inline'"], FORM_ACTION=["https:"])

[...]

@method_decorator(saml2_csp, name='dispatch')
class LoginView(...):
@peppelinux
Copy link
Member

Good catch

could you please open a Pull Request with this relevant security feature?
I would like to have a mention about this feature in the documentation as well, if you agree

I think that this would be something for release 1.9.0 if you agree

@prauscher
Copy link
Contributor Author

Thanks for your support, I opened #392, which currently contains yet untested code. For documentation I could not find a suitable spot at first glance, maybe add it to the FAQ?

@peppelinux
Copy link
Member

thank you for the amazing report and the quick and concrete code proposal

I requested three changes in your PR just related to the project and not to your code.

if you feel comfortable in having it in the FAQ please include it in the FAQ

peppelinux pushed a commit that referenced this issue Dec 27, 2023
Make sure djangosaml2 works in csp-enabled applications too (fix #391)
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

No branches or pull requests

2 participants