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

Currently unable to add Nonce for Content Security Policy #17

Open
dgabrahams opened this issue Dec 19, 2022 · 0 comments
Open

Currently unable to add Nonce for Content Security Policy #17

dgabrahams opened this issue Dec 19, 2022 · 0 comments

Comments

@dgabrahams
Copy link

dgabrahams commented Dec 19, 2022

The wagtail-schema.org app seems to use this template tag to output the script element:

    json_out = json.dumps(entity, cls=JSONLDEncoder, sort_keys=True)
    return mark_safe('<script type="application/ld+json">{}</script>'.format(
        json_out))

To work with django-csp it should be modified to check if request.csp_nonce is available and if yes add the nonce so the final output will be:
<script type="application/ld+json" nonce="xxx">...</script>

It might also be prudent to allow a more versatile approach where custom nonces can be passed, this way users are not tied to having to use django-csp

Update:
I made wagtail-schema.org compatible with django-csp by making the following changes in a custom templatetag file:

import json

from django import template
from django.utils.html import conditional_escape
from django.utils.safestring import mark_safe

from wagtailschemaorg.encoder import JSONLDEncoder
from wagtailschemaorg.registry import registry
from wagtailschemaorg.templatetags.wagtailschemaorg_tags import *

register = template.Library()


def nl(xs):
    return mark_safe('\n'.join(map(conditional_escape, xs)))


def ld_for_site(site, nonce=None):
    f = lambda lst: ld_print_entity(lst, nonce)
    return nl(map(f, registry.get_entities(site)))


def ld_print_entity(entity, nonce):
    json_out = json.dumps(entity, cls=JSONLDEncoder, sort_keys=True)
    return mark_safe('<script type="application/ld+json"{}>{}</script>'.format(nonce,json_out))


@register.simple_tag(takes_context=True)
def custom_ld_for_site(context, site=None):
    if site is None:
        site = Site.find_for_request(context["request"])

    nonce = ""
    if context.request.csp_nonce:
        nonce = f" nonce=\"{context.request.csp_nonce}\""

    return ld_for_site(site, nonce)

Include on a Django template:

{% custom_ld_for_site %}
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

1 participant