2015-06-24 21 views
5

jestem wysłanie żądania POST z klienta iOSKolba: weryfikacja CSRF udało

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

Oto odpowiedź:

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

Używam Flask ramy i pythonanywhere za hosting.

Działa poprawnie, gdy przeładowuję skrypt Pythona, ale po kilku godzinach/dniach weryfikacja CSRF nie powiodła się.

Nawet jeśli próbuję wyłączyć weryfikację CSRF w moim app.py z:

app.config['WTF_CSRF_CHECK_DEFAULT'] = False 

App.py skryptu:

//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) 

Jak mogę zrealizować weryfikację CSRF poprawnie lub jak wyłączyć to?

+0

Kolba nie ma wbudowanej ochrony CSRF. Czy dodajesz ją za pomocą Flask-WTF lub podobnego rozszerzenia? – jonafato

+0

Nie, i nie chcę tego używać, nie rozumiem, dlaczego otrzymuję ten błąd. Nie używam flask_wtf.csrf, CsrfProtect i nie robię CsrfProtect (app) w app.py. –

+0

Jeśli jest to możliwe, chcę go wyłączyć, ale nie wiem, dlaczego app.config ['WTF_CSRF_CHECK_DEFAULT'] = False nie działa w app.py. –

Odpowiedz

0

masz linię w kodzie, który jest [request setValue:@"https://example.com" forHTTPHeaderField: @"Referer"];

czy nie ustawić go na prawidłowy adres URL? Zły odnośnik jest jednym ze sposobów uzyskania błędu przekierowania.

Conrad

+0

Tak, to jest poprawny adres URL, ponieważ działa przez kilka godzin lub dzień, w którym ponownie ładuję aplikację internetową, a następnie pojawia się błąd weryfikacji CSRF. –

+0

po powrocie pozostanie do czasu ponownego załadowania aplikacji internetowej? czy to znika po kilku uderzeniach – conrad

1

PythonAnywhere deweloper tutaj, przeksięgowanie co po prostu umieścić na naszym forum. To okazało się dość niejasnym problemem na naszej platformie hostingowej, a my właśnie pchnęliśmy łatkę systemową, która to naprawia.

Oto, co to było: jeśli aplikacja internetowa została wyłączona z jakiegoś powodu (restart systemu, pewne rodzaje usterki, nadmierne zużycie zasobów, może hibernacja), to tylko żądanie GET obudziłoby ją. W szczególności żądania POST będą odrzucane z błędem CSRF (wygenerowanym przez nasz kod, który ma uruchomić aplikację internetową), a aplikacja nie zostanie przebudzona. Jeśli więc twoja aplikacja przetwarza głównie żądania POST, zobaczysz ten problem. To zdecydowanie wydaje się pasować do problemu, jak go opisujesz.

Nasz nowy kod budzi aplikację po otrzymaniu POST. Pozostaje tylko jeden drobny problem - pierwsze zgłoszenie POST, które je przebudzi, otrzyma odpowiedź "503 Service Unavailable" z ustawionym nagłówkiem "Retry-after" na "5". Jeśli sobie z tym poradzisz i ponowisz próbę, następne żądanie zadziała. Uważamy, że przeglądarki wykonują to automatycznie, ale niestety biblioteka żądań nie jest domyślnie.