From 91d88072f117a38f9c48ec2ef786648b0dd3426b Mon Sep 17 00:00:00 2001 From: lukaw3d Date: Sat, 25 Jun 2022 21:23:20 +0200 Subject: [PATCH] Avoid inline script execution for injecting CSRF token Scripts with type="application/json" or "text/plain" are not executed, so we can use them to inject dynamic CSRF data, without allowing inline-script execution in Content-Security-Policy. --- rest_framework/static/rest_framework/js/csrf.js | 1 + rest_framework/templates/rest_framework/admin.html | 10 +++++----- rest_framework/templates/rest_framework/base.html | 10 +++++----- tests/test_templates.py | 4 ++-- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/rest_framework/static/rest_framework/js/csrf.js b/rest_framework/static/rest_framework/js/csrf.js index 6e4bf39a79..0d8444f279 100644 --- a/rest_framework/static/rest_framework/js/csrf.js +++ b/rest_framework/static/rest_framework/js/csrf.js @@ -38,6 +38,7 @@ function sameOrigin(url) { !(/^(\/\/|http:|https:).*/.test(url)); } +window.drf = JSON.parse(document.getElementById('drf_csrf').textContent); var csrftoken = window.drf.csrfToken; $.ajaxSetup({ diff --git a/rest_framework/templates/rest_framework/admin.html b/rest_framework/templates/rest_framework/admin.html index 1281220b28..caa114c8c2 100644 --- a/rest_framework/templates/rest_framework/admin.html +++ b/rest_framework/templates/rest_framework/admin.html @@ -244,11 +244,11 @@ {% endif %} {% block script %} - diff --git a/rest_framework/templates/rest_framework/base.html b/rest_framework/templates/rest_framework/base.html index a88e1591c6..82afac1e5b 100644 --- a/rest_framework/templates/rest_framework/base.html +++ b/rest_framework/templates/rest_framework/base.html @@ -287,11 +287,11 @@

{{ name }}

{% endif %} {% block script %} - diff --git a/tests/test_templates.py b/tests/test_templates.py index 0dba78ea22..5b5bb29d8b 100644 --- a/tests/test_templates.py +++ b/tests/test_templates.py @@ -6,7 +6,7 @@ def test_base_template_with_context(): context = {'request': True, 'csrf_token': 'TOKEN'} result = render({}, 'rest_framework/base.html', context=context) - assert re.search(r'\bcsrfToken: "TOKEN"', result.content.decode()) + assert re.search(r'"csrfToken": "TOKEN"', result.content.decode()) def test_base_template_with_no_context(): @@ -14,4 +14,4 @@ def test_base_template_with_no_context(): # so it can be easily extended. result = render({}, 'rest_framework/base.html') # note that this response will not include a valid CSRF token - assert re.search(r'\bcsrfToken: ""', result.content.decode()) + assert re.search(r'"csrfToken": ""', result.content.decode())