Django-CSP - AJAX 带有普通 JS 的请求被 CSP 阻止
Django-CSP - AJAX request with vanilla JS blocked by CSP
我有一个基于 Django 的 D&D-wiki 网页,我在空闲时间使用它来了解有关 Web 开发的更多信息。
我最近使用 django-csp. 实现了一个内容安全策略,这很顺利,而且转换相当轻松,因为我只有 20 个左右的模板要处理。这是我的 CSP 设置:
//Django settings.py
CSP_DEFAULT_SRC = ("'none'",)
CSP_STYLE_SRC = ("'self'", 'stackpath.bootstrapcdn.com', 'fonts.googleapis.com', "'unsafe-inline'", 'cdn.jsdelivr.net', 'cdnjs.cloudflare.com', 'rawcdn.githack.com', 'maxcdn.bootstrapcdn.com',)
CSP_SCRIPT_SRC = ("'self'", 'localhost', "default-src", 'stackpath.bootstrapcdn.com', 'code.jquery.com', 'cdn.jsdelivr.net', 'cdnjs.cloudflare.com','maxcdn.bootstrapcdn.com',)
CSP_IMG_SRC = ("'self'", 'ipw3.org', 'data:', 'cdn.jsdelivr.net', 'cdnjs.cloudflare.com', 'i.imgur.com',)
CSP_FONT_SRC = ("'self'", 'fonts.gstatic.com', 'maxcdn.bootstrapcdn.com',)
CSP_MEDIA_SRC = ("'self'",)
CSP_INCLUDE_NONCE_IN = ('style-src',)
最近开始学习 AJAX 请求并想实现一个简单的 POST 请求。
可悲的是,我的 CSP 阻止了这个请求,我认为应该允许这个请求,因为我在 CSP_SCRIPT_SRC:
中允许了 self 和 localhost
//JS Event Listener that creates and sends the AJAX request
document.getElementById('create-timstamp').addEventListener('click', function(event){
const isValid = validateForm();
if (isValid){
xhr = new XMLHttpRequest();
xhr.open('POST', getCreateTimestampURL(), true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
const csrf = document.querySelector('input[name="csrfmiddlewaretoken"]').value;
xhr.setRequestHeader("X-CSRF-TOKEN", csrf);
xhr.onload = function(){
document.querySelector('.timestamp-create-box').remove();
}
const timestampForm = document.forms['timestamp-form'];
const timestamp_seconds = toTimeInt(timestampForm['time'].value);
const timestamp_name = timestampForm['name'].value;
const data = `name=${timestamp_name}&time=${timestamp_seconds}`;
xhr.send(data);
return false;
}
//For completion's sake here also the helper methods used by the event listener
function getCreateTimestampURL(){
return document.querySelector('#add-timestamp').dataset.timestampcreateurl;
}
function toTimeInt(timestampString){
const hours = parseInt(timestampString.substring(0,2));
const minutes = parseInt(timestampString.substring(3,5));
const seconds = parseInt(timestampString.substring(6,8));
return 3600*hours + 60*minutes + seconds;
}
这里是浏览器的响应:
//Webbrowser console output after triggering the event
Content Security Policy: The page’s settings blocked the loading of a resource at http://localhost:8002/files/timestamp/1/17/new (“default-src”).
所以我知道我做错了什么,但我不确定是什么。我知道我需要以某种方式调整我的 CSP 设置,但我已经允许本地主机脚本,还需要什么?
又读了一遍the django-csp documentation,我终于找到了我要找的条目。不知道前几次我是怎么错过的。
你要更改的条目是CSP_CONNECT_SRC
,自然需要让("'self'",)
能够发送AJAX个请求。
那 不是 意味着上面的请求代码可以工作。它获取 CSRF Token 的方式是 non-functional 并导致错误。这刚刚通过了 CSP 阻塞。
我有一个基于 Django 的 D&D-wiki 网页,我在空闲时间使用它来了解有关 Web 开发的更多信息。 我最近使用 django-csp. 实现了一个内容安全策略,这很顺利,而且转换相当轻松,因为我只有 20 个左右的模板要处理。这是我的 CSP 设置:
//Django settings.py
CSP_DEFAULT_SRC = ("'none'",)
CSP_STYLE_SRC = ("'self'", 'stackpath.bootstrapcdn.com', 'fonts.googleapis.com', "'unsafe-inline'", 'cdn.jsdelivr.net', 'cdnjs.cloudflare.com', 'rawcdn.githack.com', 'maxcdn.bootstrapcdn.com',)
CSP_SCRIPT_SRC = ("'self'", 'localhost', "default-src", 'stackpath.bootstrapcdn.com', 'code.jquery.com', 'cdn.jsdelivr.net', 'cdnjs.cloudflare.com','maxcdn.bootstrapcdn.com',)
CSP_IMG_SRC = ("'self'", 'ipw3.org', 'data:', 'cdn.jsdelivr.net', 'cdnjs.cloudflare.com', 'i.imgur.com',)
CSP_FONT_SRC = ("'self'", 'fonts.gstatic.com', 'maxcdn.bootstrapcdn.com',)
CSP_MEDIA_SRC = ("'self'",)
CSP_INCLUDE_NONCE_IN = ('style-src',)
最近开始学习 AJAX 请求并想实现一个简单的 POST 请求。 可悲的是,我的 CSP 阻止了这个请求,我认为应该允许这个请求,因为我在 CSP_SCRIPT_SRC:
中允许了 self 和 localhost//JS Event Listener that creates and sends the AJAX request
document.getElementById('create-timstamp').addEventListener('click', function(event){
const isValid = validateForm();
if (isValid){
xhr = new XMLHttpRequest();
xhr.open('POST', getCreateTimestampURL(), true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
const csrf = document.querySelector('input[name="csrfmiddlewaretoken"]').value;
xhr.setRequestHeader("X-CSRF-TOKEN", csrf);
xhr.onload = function(){
document.querySelector('.timestamp-create-box').remove();
}
const timestampForm = document.forms['timestamp-form'];
const timestamp_seconds = toTimeInt(timestampForm['time'].value);
const timestamp_name = timestampForm['name'].value;
const data = `name=${timestamp_name}&time=${timestamp_seconds}`;
xhr.send(data);
return false;
}
//For completion's sake here also the helper methods used by the event listener
function getCreateTimestampURL(){
return document.querySelector('#add-timestamp').dataset.timestampcreateurl;
}
function toTimeInt(timestampString){
const hours = parseInt(timestampString.substring(0,2));
const minutes = parseInt(timestampString.substring(3,5));
const seconds = parseInt(timestampString.substring(6,8));
return 3600*hours + 60*minutes + seconds;
}
这里是浏览器的响应:
//Webbrowser console output after triggering the event
Content Security Policy: The page’s settings blocked the loading of a resource at http://localhost:8002/files/timestamp/1/17/new (“default-src”).
所以我知道我做错了什么,但我不确定是什么。我知道我需要以某种方式调整我的 CSP 设置,但我已经允许本地主机脚本,还需要什么?
又读了一遍the django-csp documentation,我终于找到了我要找的条目。不知道前几次我是怎么错过的。
你要更改的条目是CSP_CONNECT_SRC
,自然需要让("'self'",)
能够发送AJAX个请求。
那 不是 意味着上面的请求代码可以工作。它获取 CSRF Token 的方式是 non-functional 并导致错误。这刚刚通过了 CSP 阻塞。