2015-06-24 15 views
5

io mando una richiesta POST da un client iOSFlask: CSRF verifica non è riuscita

-(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 
    } 
} 

Ecco la risposta:

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

sto utilizzando framework Flask e pythonanywhere per l'hosting.

Funziona correttamente quando ricarico lo script python ma dopo poche ore/giorni la verifica CSRF non è riuscita a riapparire.

Anche se cerco di disattivare la verifica CSRF nel mio app.py con:

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) 

Come posso implementare la verifica CSRF correttamente o come disabilitarlo?

+0

Flask non ha la protezione CSRF integrata. La si aggiunge con Flask-WTF o un'estensione simile? – jonafato

+0

No, e non voglio usarlo, non capisco perché ricevo questo errore. Non uso flask_wtf.csrf, CsrfProtect e non faccio CsrfProtect (app) in app.py. –

+0

Se è possibile, voglio disabilitarlo ma non so perché app.config ['WTF_CSRF_CHECK_DEFAULT'] = False non funziona in app.py. –

risposta

0

si dispone di una linea nel codice che è [request setValue:@"https://example.com" forHTTPHeaderField: @"Referer"];

non hai impostato per l'URL corretto? Un referente sbagliato è un modo per ottenere un errore cross-site.

Conrad

+0

Sì, è l'URL corretto perché funziona per alcune ore o un giorno in cui ricarico l'app Web, quindi l'errore di verifica CSRF ritorna. –

+0

dopo il suo ritorno rimane finché non si ricarica la webapp? o se ne va dopo averlo colpito un paio di volte – conrad

1

PythonAnywhere sviluppatore qui, reinserire quello che abbiamo appena messo sul nostro forum. Questo si è rivelato un problema abbastanza oscuro sulla nostra piattaforma di hosting e abbiamo appena inserito una patch di sistema che la risolve.

Ecco quello che era: se una web app è stato chiuso per qualche motivo (riavvio del sistema, alcuni tipi di problema tecnico, l'utilizzo delle risorse eccessiva, forse ibernazione) allora solo una richiesta GET avrebbero svegliarlo. Le richieste POST, in particolare, verrebbero rifiutate con un errore CSRF (generato dal nostro codice che ha lo scopo di avviare l'app Web) e l'app non sarebbe stata riattivata. Quindi se la tua app è quella che elabora principalmente richieste POST, vedresti questo problema. Questo sicuramente sembra adattarsi al problema come lo descrivi.

Il nostro nuovo codice attiva l'applicazione quando viene ricevuto un POST. Rimane un piccolo problema: la prima richiesta POST che lo riattiva riceverà una risposta "503 Servizio non disponibile" con l'intestazione "retry-after" impostata su "5". Se gestisci questo e fai il tentativo, la prossima richiesta funzionerà. Riteniamo che i browser lo facciano automaticamente, ma sfortunatamente la libreria delle richieste non è predefinita.