Reputation: 27351
Given the following series of events
Is the resulting csrf failure expected, and if so, are there any solutions that will give the user a better experience?
Upvotes: 0
Views: 748
Reputation: 27351
For this exact issue, and provided Django's CSRF_COOKIE_HTTPONLY
has its default value of False, this onfocus handler seems to work:
$(document).ready(function () {
$(window).on('focus', function () {
var cookie_csrf = dk.web.cookie.get('csrftoken'); // or Cookie.get(..) or something similar
var dom_csrf = $('[name=csrfmiddlewaretoken]:first');
if (cookie_csrf !== dom_csrf) {
// other tab has caused the csrf cookie to change
$('[name=csrfmiddlewaretoken]').each(function () {
$(this).val(cookie_csrf);
});
}
});
});
it seems a bit hackish, so perhaps refreshing the page is "better":
if (cookie_csrf !== dom_csrf) {
window.location.reload(true); // reload the current page, without using the cache
}
refreshing the page will get any changes to the page that results from logging in, but delete any input the user has entered.
It's safe to access the csrf token from .js assuming you have no XSS vulnerabilities (which is generally assumed when it comes to csrf).
This technique relies on the fact that the value of the csrf token in the cookie and in the dom are identical, which they are in Django by design.
Upvotes: 0
Reputation: 18938
Yes, this is part of the security system. Given that the CSRF token belonged to the anonymous user could potentially be generated/acquired by the attacker (as they are anonymous users also), it is definitely not a wise idea to use that token after the user has logged in. Django documents this behavior as a security measure, and they have a relevant ticket documenting why they do this.
This is also why some sites (such as github) will warn the user that they need to reload the page on all other tabs of the users' browser session if a login/logout was done in one tab. There is no safe measure to avoid this.
Upvotes: 2