Flask : CSRF verification failed
Asked Answered
C

2

6

I am sending a POST request from an iOS client

-(void)loadFavorite:(NSArray*)favorites{

    //data and url preparation

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setValue:@"https://example.com" forHTTPHeaderField: @"Referer"];

    [request setValue:[NSString stringWithFormat:@"%tu", [requestData length]] forHTTPHeaderField:@"Content-Length"];
    [request setHTTPBody: requestData];

    if ([Tools isNetWorkConnectionAvailable]) {
        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
            //response handle
    }
}

Here is the response :

<div id="summary">
  <h1>Forbidden <span>(403)</span></h1>
  <p>CSRF verification failed. Request aborted.</p>
</div>

I'm using Flask framework and pythonanywhere for hosting.

It works fine when I reload the python script but after few hours/days the CSRF verification failed error reappear.

Even if I try to disable the CSRF verification in my app.py with :

app.config['WTF_CSRF_CHECK_DEFAULT'] = False

App.py script :

//some import error handlers ...

app = Flask(__name__)
app.config['WTF_CSRF_CHECK_DEFAULT'] = False

@app.route('/api/favorites', methods=['POST'])
def get_favorites_beaches():
    if not request.json or not 'favorite' in request.json:
        abort(400)
    //data process

if __name__ == '__main__':
    app.run(host='0.0.0.0',debug=True)

How can I implement the CSRF verification correctly or how to disable it ?

Childbirth answered 24/6, 2015 at 16:58 Comment(5)
Flask doesn't have CSRF protection built in. Are you adding it with Flask-WTF or a similar extension?Somite
No, and I don't want to use it, I don't understand why I receive this error. I don't use flask_wtf.csrf, CsrfProtect and I don't do CsrfProtect(app) in app.py.Childbirth
If it's possible I want to disable it but I don't know why app.config['WTF_CSRF_CHECK_DEFAULT'] = False doesn't work in app.py.Childbirth
If you aren't using WTF then 'WTF_CSRF_CHECK_DEFAULT' isn't going to work.Elena
Ok so should I import Flask-WTF or a similar extension to make WTF_CSRF_CHECK_DEFAULT working ?Childbirth
P
1

PythonAnywhere developer here, reposting what we just put on our forums. This turned out to be a fairly obscure problem on our hosting platform, and we've just pushed a system patch that fixes it.

Here's what it was: if a web app was shut down for some reason (system reboot, certain kinds of glitch, excessive resource usage, maybe hibernation) then only a GET request would wake it up. POST requests, in particular, would be rejected with a CSRF error (generated by our code that's meant to start up the web app), and the app wouldn't be woken up. So if your app is one that processes mostly POST requests, you'd see this problem. This definitely seems to fit the issue as you describe it.

Our new code wakes up the app when a POST is received. One slight issue remains -- the first POST request that wakes it up will receive a "503 Service Unavailable" response with the "retry-after" header set to "5". If you handle this and do the retry, then the next request will work. We believe that browsers do that automatically, but unfortunately the requests library doesn't by default.

Poulson answered 14/4, 2016 at 15:11 Comment(0)
R
0

you have a line in your code that is [request setValue:@"https://example.com" forHTTPHeaderField: @"Referer"];

did you not set it to the correct url? A wrong referer is one way you would get a cross site error.

Conrad

Rustin answered 26/6, 2015 at 6:3 Comment(2)
Yes it's the correct url because it's works for a few hours or a day when I reload the web app then the CSRF verification error comes back.Childbirth
after it comes back does it stay till you reload the webapp? or does it go away after you hit it a couple timesRustin

© 2022 - 2024 — McMap. All rights reserved.