2009-10-30 3 views
54

Nie można wyłączyć oprogramowania pośredniego django csrf. Skomentowałem to z mojego Middleware mojego projektu, ale moje loginy zawodziły z powodu problemów z CSRF. Pracuję z pnia Django. Jak CSRF może powodować problemy, jeśli nie jest włączone w oprogramowaniu pośredniczącym?Django Framework CSRF nie może być wyłączony i łamie moją witrynę

Muszę to wyłączyć, ponieważ na mojej stronie jest dużo żądań POST, że CSRF właśnie się zepsuł. Jakieś opinie na temat całkowitego wyłączenia CSRF w projekcie django trunk?

"Nowe" ramy CSRF z pnia Django przerywają zewnętrzną stronę, która przychodzi i robi POST pod adresem URL, który im podaję (jest to część restrykcyjnego API). Nie mogę wyłączyć ramy CSRF jak powiedziałem wcześniej, jak mogę rozwiązać ten problem?

+0

przyjąć prawidłową odpowiedź proszę – necromancer

+0

Odpowiedź z @shreddd jest chyba lepszym wyborem niż akceptowanych odpowiedź. – boatcoder

Odpowiedz

11

Zobacz odpowiedzi poniżej, aby uzyskać lepsze rozwiązanie. Odkąd to napisałem, wiele się zmieniło. Istnieją teraz lepsze sposoby na wyłączenie CSRF.

Czuję twój ból. Niedopuszczalne jest, aby struktura zmieniała takie podstawowe funkcje. Nawet jeśli chcę zacząć używać tego od teraz, mam już istniejące witryny na tym samym komputerze, które dzielą się kopią django. Zmiany takie jak ta powinny wymagać aktualizacji głównych wersji. 1.x -> 2.x.

W każdym razie, aby to naprawić, właśnie skomentowałem to i przestałem aktualizować Django tak często.

pliku: django/middleware/csrf.py Wokół linii 160:

  # check incoming token 
#   request_csrf_token = request.POST.get('csrfmiddlewaretoken', None) 
#   if request_csrf_token != csrf_token: 
#    if cookie_is_new: 
#     # probably a problem setting the CSRF cookie 
#     return reject("CSRF cookie not set.") 
#    else: 
#     return reject("CSRF token missing or incorrect.") 
+1

Minęły lata, ale komentowanie tej sekcji wydaje mi się nadal najlepszą opcją. Inne rozwiązania zwykle działają w niektórych, ale nie we wszystkich przypadkach. – Drachenfels

6

Generalnie nie należy wyłączyć ochronę CSRF, ponieważ ten sposób otwiera się luk bezpieczeństwa. Jeśli upierasz się, choć ...

nowa sposób wykonywania ochrony CSRF wylądował w bagażniku właśnie ostatnio.Czy witryna jest przypadkiem nadal skonfigurowany, aby zrobić to stary sposób? Oto the docs for The New Way™ i tutaj są docs for The Old Way™.

+1

Dzięki za informację, nie powiedziałeś mi, jak całkowicie wyłączyć CSRF, mam stronę produkcyjną, która przestała działać dla płacących klientów, ponieważ byłam zignorowana przez ten "nowy" sposób robienia rzeczy, które nie są wstecznie kompatybilne. Ale to jest problem, który powoduje problem, pracuję nad szybkim aktualizowaniem do nowego/starego sposobu. – MikeN

+0

Oto niektóre z dyskusji z listy dyskusyjnej programistów: http://groups.google.com/group/django-developers/browse_thread/thread/ac771d10d58340cb Może to pomoże w wyłączeniu/aktualizacji. –

+0

Istnieje dekorator widoku do użycia: @csrf_exempt, jeśli wstawisz ten dekorator, struktura CSRF zignoruje jego sprawdzanie dla tego żądania. Nie mogę się nadziwić, jak powstała pułapka CSRF, jest wypalana w ramce auth, więc nie możesz jej wyłączyć, jeśli użyjesz auth do logowania. – MikeN

125

Tak, Django ram CSRF może być wyłączona.

Aby ręcznie wykluczyć funkcję widoku z obsługi przez dowolne oprogramowanie warstwy CSRF, można użyć dekoratora csrf_exempt, który znajduje się w module django.views.decorators.csrf. Na przykład: (see doc)

from django.views.decorators.csrf import csrf_exempt           
@csrf_exempt                     
def my_view:                    
    return Httpresponse("hello world") 

..i następnie usunąć {% csrf_token %} wewnątrz formularzy z szablonu, lub pozostawić inne rzeczy bez zmian, jeśli nie obejmowały go w formach.

+1

+1 o wiele lepiej używać zalecanej metody, aby wyłączyć je selektywnie, zamiast wyłączać go wszędzie! – Seth

+2

Świetna odpowiedź, potrzebuje więcej upvotes – GDR

+2

Zgadzam się, że to powinna być akceptowana odpowiedź. Zasadniczo nie hakuj biblioteki, gdy jej interfejs API zapewnia już taką funkcjonalność, jakiej potrzebujesz. –

4

Po prostu próbowałem usunąć odniesienia do klas oprogramowania pośredniego csrf z mojego settings.py, zadziałało. Nie jestem pewien, czy jest to akceptowalne. Wszelkie komentarze? Usunięto poniższe dwie linie -

 'django.middleware.csrf.CsrfViewMiddleware', 
     'django.middleware.csrf.CsrfResponseMiddleware', 
+0

ok, rozumiem. Zepsuło to mój admin, więc rozwiązanie poprawki wydaje się najlepsze (choć tego nie wypróbowałem). – Yateen

+0

Nie działa dla mnie. – Bryce

81

Możesz wyłączyć to w oprogramowaniu pośredniczącym.

W Twojej settings.py dodaj linię do MIDDLEWARE_CLASSES:

MIDDLEWARE_CLASSES = (

    myapp.disable.DisableCSRF, 

) 

Tworzenie Wyłącz.py w MojaApl z następującym

class DisableCSRF(object): 
    def process_request(self, request): 
     setattr(request, '_dont_enforce_csrf_checks', True) 

Zasadniczo jeśli ustawić _dont_enforce_csrf_checks w swoim wniosku, powinno być OK.

+0

Dzięki! Dokładnie to, czego potrzebowałem. Używam systemu komentowania Django, ale ponieważ strona zawierająca formularz jest zapisana w pamięci podręcznej, sprawdzanie poprawności csrf nie działa. –

+1

To jest najlepszy sposób na wyłączenie csrf dla całej witryny, całkiem proste. Aby selektywnie wyłączyć, a nie było to pytanie, możesz użyć drugiej odpowiedzi na temat @csrf_exempt. – Pykler

+0

Ta jedna jest poprzednia, inne były zbyt ogólne lub po prostu maskowały fakt niepowodzenia csrf dla widoku. Ten właściwie wyłącza się dla pewnej aplikacji, bez maskowania niepowodzeń ... –

0

moja wersja django to 1.11. middleware powinno być tak:

from django.utils.deprecation import MiddlewareMixin 


class DisableCSRF(MiddlewareMixin): 
    def process_request(self, request): 
     setattr(request, '_dont_enforce_csrf_checks', True)