mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-21 17:16:47 +03:00
Avoid inline script execution for injecting CSRF token (#7016)
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.
This commit is contained in:
parent
f0095b4de2
commit
6ec6ddea9b
|
@ -38,6 +38,7 @@ function sameOrigin(url) {
|
||||||
!(/^(\/\/|http:|https:).*/.test(url));
|
!(/^(\/\/|http:|https:).*/.test(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.drf = JSON.parse(document.getElementById('drf_csrf').textContent);
|
||||||
var csrftoken = window.drf.csrfToken;
|
var csrftoken = window.drf.csrfToken;
|
||||||
|
|
||||||
$.ajaxSetup({
|
$.ajaxSetup({
|
||||||
|
|
|
@ -244,11 +244,11 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
<script>
|
<script type="application/json" id="drf_csrf">
|
||||||
window.drf = {
|
{
|
||||||
csrfHeaderName: "{{ csrf_header_name|default:'X-CSRFToken' }}",
|
"csrfHeaderName": "{{ csrf_header_name|default:'X-CSRFToken' }}",
|
||||||
csrfToken: "{{ csrf_token }}"
|
"csrfToken": "{{ csrf_token }}"
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<script src="{% static "rest_framework/js/jquery-3.5.1.min.js" %}"></script>
|
<script src="{% static "rest_framework/js/jquery-3.5.1.min.js" %}"></script>
|
||||||
<script src="{% static "rest_framework/js/ajax-form.js" %}"></script>
|
<script src="{% static "rest_framework/js/ajax-form.js" %}"></script>
|
||||||
|
|
|
@ -287,11 +287,11 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
<script>
|
<script type="application/json" id="drf_csrf">
|
||||||
window.drf = {
|
{
|
||||||
csrfHeaderName: "{{ csrf_header_name|default:'X-CSRFToken' }}",
|
"csrfHeaderName": "{{ csrf_header_name|default:'X-CSRFToken' }}",
|
||||||
csrfToken: "{% if request %}{{ csrf_token }}{% endif %}"
|
"csrfToken": "{% if request %}{{ csrf_token }}{% endif %}"
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<script src="{% static "rest_framework/js/jquery-3.5.1.min.js" %}"></script>
|
<script src="{% static "rest_framework/js/jquery-3.5.1.min.js" %}"></script>
|
||||||
<script src="{% static "rest_framework/js/ajax-form.js" %}"></script>
|
<script src="{% static "rest_framework/js/ajax-form.js" %}"></script>
|
||||||
|
|
|
@ -6,7 +6,7 @@ from django.shortcuts import render
|
||||||
def test_base_template_with_context():
|
def test_base_template_with_context():
|
||||||
context = {'request': True, 'csrf_token': 'TOKEN'}
|
context = {'request': True, 'csrf_token': 'TOKEN'}
|
||||||
result = render({}, 'rest_framework/base.html', context=context)
|
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():
|
def test_base_template_with_no_context():
|
||||||
|
@ -14,4 +14,4 @@ def test_base_template_with_no_context():
|
||||||
# so it can be easily extended.
|
# so it can be easily extended.
|
||||||
result = render({}, 'rest_framework/base.html')
|
result = render({}, 'rest_framework/base.html')
|
||||||
# note that this response will not include a valid CSRF token
|
# 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())
|
||||||
|
|
Loading…
Reference in New Issue
Block a user