2010-04-20 16 views
5

Niedawno rozpocząłem pracę nad Django, a teraz moja aplikacja jest już prawie na ukończeniu i zacząłem zastanawiać się nad bezpieczeństwem i najlepszymi praktykami.Django Zobacz bezpieczeństwo i najlepsze praktyki

Mam widok, który generuje stronę i różne funkcje w poście strony żądań AJAX do poszczególnych widoków. Na przykład mam widok o nazwie show_employees i mogę usuwać i aktualizować pracowników, przekazując żądanie postu do widoków delete_employee i update_employee.

  1. Włożyłam @login_required dekoratorów przed każdym z tych widoków, ponieważ nie chcę nikomu dostępu do nich bez uwierzytelniania. Czy to w porządku?

  2. W widokach delete_employee i update_employee odpowiadam tylko na żądanie, jeśli jest to żądanie POST AJAX (uisng is_ajax()). Czy to w porządku?

  3. Zwracam "sukces", gdy widok powiedzie się, wykonując to, co jest potrzebne, i błąd, gdy w moim formularzu występuje błąd sprawdzania poprawności, ale nadal nie obsługuję innych wyjątków. Jak mam to zrobić? Czy powinienem zwrócić standardową stronę 500 poprzez odpowiedź AJAX, taką jak this, zawijając widok blokiem try-except, aby obsłużyć wszystkie wyjątki?

  4. Czy mogę coś jeszcze zrobić, aby zabezpieczyć mój widok?

Oto przykładowa kopalni:

@login_required 
    def add_site(request): 
     data = {} 
     if request.method == 'POST': 
      if request.is_ajax(): 
       form = AddSiteForm(request.user, request.POST) 
       if form.is_valid(): 
        site = form.save(commit=False) 
        site.user = request.user 
        site.save() 
        data['status'] = 'success' 
        data['html'] = render_to_string('site.html', locals(), context_instance=RequestContext(request)) 
        return HttpResponse(simplejson.dumps(data), mimetype='application/json') 
       else: 
        data['status'] = 'error' 
        data['errors'] = {} 
        for field, error in form.errors.iteritems(): 
         data['errors']['id_'+field] = strip_tags(unicode(error)) 
        return HttpResponse(simplejson.dumps(data), mimetype='application/json') 

Dziękuję.

Odpowiedz

11

Cóż, zamiast używać tylko @login_required, sugeruję, aby przyjrzeć się permissions framework i powiązanym permission required decorator. W ten sposób możesz dostroić ograniczenia dostępu dla użytkownika lub grupy. Łatwiej jest też i bezpieczniej zmienić zachowanie użytkowników po uzyskaniu pozwolenia niż przy użyciu tylko dekoratora login_required. Załóżmy, że masz teraz tylko administratorów, ale później chcesz dodać innych użytkowników, łatwo wtedy przegapić dekorator wymagający logowania i przyznając tym użytkownikom dostęp do widoków admina. Nie będziesz mieć tego problemu z prawidłowo zdefiniowanymi uprawnieniami.

Następnie is_ajax sprawdza tylko nagłówek HTTP_X_REQUESTED_WITH. Nie ma to nic wspólnego z bezpieczeństwem, ale z zachowaniem przyjaznym dla użytkownika. W ten sposób uniemożliwisz zwykłemu użytkownikowi przypadkowe otwarcie tej strony w przeglądarce i uzyskanie pewnych dziwnych danych. To nie pomaga w bezpieczeństwie, każdy przyzwoity haker może ustawić dodatkowy nagłówek HTTP :).

Niestosowanie wyjątków może być potencjalnie niebezpieczne, jeśli przypadkowo zostawisz na DEBUG=True, w takim przypadku django dostarczy fragmenty kodu i ślady po śladach, potencjalnie oddające słabości. Ale jeśli ta opcja jest wyłączona, django wyświetli swoją własną stronę błędu 500. Moja sugestia brzmi: poszukaj wszystkich oczekiwanych wyjątków django (nie jest ich wiele) i upewnij się, że złapałeś je poprawnie. Dalej, chciałbym powiedzieć, niech inny wyjątek będzie obsługiwany przez django, django nadal zapewni możliwości generowania śladów i innych informacji debugowania i wysłania ich do administratorów zamiast wyświetlania ich na miejscu. Jeśli zauważysz wszystkie nieoczekiwane błędy, to zachowanie nie będzie dostępne bezpośrednio, może pozostawiając Cię nieznanym na temat błędu w kodzie.

Wreszcie, pracując z danymi wejściowymi użytkownika, proponuję zapoznać się z security chapter w książce django, wyjaśnić najważniejsze zagrożenia i jak sobie z nimi poradzić w środowisku django.