mercredi 23 août 2017

Django reports referer or CSRF checking error but lets user in

I am quite new to Django, and have just started writing my first tests, and I fail to understand the situation I've discovered. My site has a login page, which makes use of CSRF token:

        <form id="login-form" method="post" action="/login">
            <input type='hidden' name='csrfmiddlewaretoken' value='2QXxnB5yTqOnEdsFVwgWfCbBam6JOvl49mnXk29mBgxVP1tvf7VWy0VvxzYtR3OT' />
            <table>
                <tr>
                    <td><input id="id_username" name="username" type="text"></td>
                </tr>
                <tr>
                    <td><input id="id_password" name="password" type="password"></td>
                </tr>

                <tr><td colspan="2">
                    <input type="submit" value="Enter" class="btn" />
                    <input type="hidden" name="next" value="/home" />
                </td></tr>     
            </table>
        </form>

This form works fine. Without passing it I cannot access "secret" data, after login I can access it.

In my tests, I have created a login() function, used to test access to restricted access data.

def login(self):
    url = PRFX + '/login'
    login_data = {'username': settings.TEST_USERNAME, 'password': settings.TEST_PASSWORD}
    headers = {'referer': url}
    r = self.session.post(url, data=login_data, headers=headers)
    self.assertEqual(r.status_code, 200)
    return r

Here starts the interesting part. Although the CSRF token is not passed in this function, it still works fine: my site tells me the test user is logged in (I get an email about it, and Axes logs every login event). I do get an email about the CSRF verification error:

[Django] WARNING (EXTERNAL IP): Forbidden (CSRF token missing or incorrect.): /login

but the site still allows the user in. What could be the reason? How could I debug it?

UPDATE Just noticed: if I don't pass the referer with POST, I get another error: [Django] WARNING (EXTERNAL IP): Forbidden (Referer checking failed - no Referer.): /login and no CSRF error— but still the test user gets in.

1 commentaire: