Aplikacje internetowe

Bełdziowe spojrzenie na aplikacje internetowe

Podstawy zabezpieczania logowania.

Moduł logowania jest podstawowym elementem każdego systemu informatycznego. Umożliwia on dostęp do wybranych zasobów tylko uprawionym użytkownikom. Jest on krytycznym miejscem aplikacji, przełamanie jego zabezpieczeń automatycznie wiąże sie z przydzieleniem atakującemu wyższych uprawnień. Sposób zabezpieczenia procesu logowania powinien być adekwatny do wrażliwości danych, do których strzeże on dostępu. Nie ma sensu tworzyć skomplikowanych systemów zabezpieczających panel administratora strony domowej, gdzie wystarczy najprostsza metoda logowania.

Istnieją jednak elementy, które powinny znaleźć się w każdym module logowania. Są to:

Autouzupełnianie formularza.

Jednym z elementów ułatwiających pracę podczas korzystanie z przeglądarek internetowych jest autouzupełnianie pól formularza. Dzięki temu udogodnieniu nie musimy za każdym razem wpisywać tych samych danych. Udogodnienie to staje się niewygodą gdy przeglądarka zapamiętuje nasze loginy. Szczególnie jest to niebezpieczne jeśli korzystamy z Internetu w miejscach publicznych.

Aby wyłączyć autouzupełnianie należy do właściwości formularza dodać:

autocomplete="off"

Minusem tego rozwiązania jest niezgodność z wytycznymi W3C. Właściwość ta została dodana przez Microsoft, a następnie zaadaptowana przez Mozillę.

Wyłączenie cache’owania stron.

Podczas przeglądania stron internetowych przeglądarki tworzą ich kopie w pamięci podręcznej dzięki czemu ponowne wejście na tą samą stronę nie wymaga łączenia się z serwerem HTTP, a jedynie wczytania kopii strony z dysku. W przypadku stron wymagających logowania zapisywanie ich kopii mogłoby umożliwić dostęp do wrażliwych danych nieupoważnionym osobom. Na szczęście możemy zabronić przeglądarkom cache’owania stron. Najlepszym sposobem na to jest wysłanie zestawu nagłówków HTTP.

header ( 'Expires: Mon, 26 Jul 1997 05:00:00 GMT' );    // czas wygaśnięcia strony
header ( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s ' ) . ' GMT' ); // czas ostatniej modyfikacji
header( 'Cache-Control: no-store, no-cache, must-revalidate' );  // wyłączenia cache'owania
header( 'Cache-Control: post-check=0, pre-check=0' , false);
header( 'Pragma: no-cache' );

Powyższy kod można zapisać korzystając tylko ze znaczników HTML. W sekcji <head /> należy dodać:

<meta http-equiv="Pragma" content="no-cache, private" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate" />
<meta http-equiv="Cache-Control" content="post-check=0, pre-check=0" />

Zablokowanie robotów.

W przypadku stron, które nie mają być publicznie dostępne warto zadbać by odwiedzające je roboty internetowe nie indeksowały ich zawartości. Dzięki temu strony nie będą dostępne w wynikach wyszukiwania (o ile robot będzie respektował poniższe polecenia). W tym celu należy utworzyć plik robots.txt o następującej zawartości:

User-agent: *
Disallow: /

Powyższy plik możemy zastąpić dodając do sekcji <head /> wpis:

<meta name="robots" content="noindex,nofollow" />

Należy jednak wziąć pod uwagę, że plik robots.txt jest bardziej respektowany przez roboty.

Określona ilość niepoprawnych logowań.

Dobrą praktyką podczas pisania modułu logowania jest ograniczenie ilości niepoprawnych logowań. Uniemożliwia to złamanie hasła do konta korzystając z ataku słownikowego oraz brute force. Najprostszym sposobem wdrożenia banlisty jest zapisywanie w sesji ilości niepoprawnych logowań i po osiągnięciu ich maksymalnego poziomu dodanie do bazy danych rekordu identyfikującego użytkownika (np. adresu IP).

Innym rodzajem blokowania dostępu może być blokowanie nie użytkownika, który się loguje, ale konta na które się loguje. Co ważne w takim przypadku należy dać możliwość szybkiego zdjęcia bana (np. poprzez wysłanie specjalnego linka na maila), dzięki czemu właściciel konta będzie mógł je odblokować w przypadku gdy zostanie ono zablokowane przez innego użytkownika.

Dostęp z określonych adresów IP.

Dodatkowym elementem zabezpieczania procesu logowania może być udzielenie dostępu do tego mechanizmu tylko użytkownikom z określonego adresu IP bądź też zakresu adresów. Zabieg taki jest przydatny np. wtedy gdy logowanie powinno być dostępne tylko z sieci firmowej. Dokonać tego możemy korzystając z pliku .htaccess poprzez umieszczenie w nim dyrektyw odpowiedzialnych za kontrole dostępu do plików.

<FilesMatch ".">
   order allow,deny
   allow from 127.0.0.   # dostęp dla zakresu adresów
   allow from 83.21.0.5 # dostęp dla jednego adresu
</FilesMatch>

Szyfrowanie połączenia.

W przypadku wrażliwych danych proces logowania powinien odbywać się wykorzystując szyfrowane połączenie (HTTPS). Dzięki temu dane potrzebne do logowania nie będą przesyłane w jawnej postaci.

Minusem tego zabezpieczenia jest konieczność wykupienia certyfikatu SSL, którego ceny wahają się od 200 do 1 800 zł + 22% VAT.


Tagi: , , , ,
Kategoria: Bezpieczeństwo, Logowanie


10 komentarzy

  1. Hash napisał(a):

    1. jak piszesz:
    Na szczęście możemy zabronić przeglądarką cache'owania stron.
    Przeczytaj i znajdź błąd :) Drobny, jednak wkurzający

    2. Sama notka może okazać się dosyć ciekawa. Prawdą jest jednak, że żadne z tych rozwiązań nie gwarantuje bezpieczeństwa. Wszak nie tylko to, jak programista zabezpieczy skrypt jest ważne, lecz także jak mocno użytkownik jest odpowiedzialny i "doinformowany".

  2. Michał "Bełdzio" Ławicki napisał(a):

    ad1. ups :) dzięki :)

    ad2. prawda, tylko żę my jako programiści nie mamy w kwestii edukowania zbyt wiele do powiedzenia :) A jeśli chodzi o bezpieczne rozwiązania to będą o tym niedługo 2 notki :)

  3. Ktos napisał(a):

    Akurat do SSL/HTTP nie jest konieczne wykupienie certyfikatu bo do zastosowań na przykład "własnych" może wystarczyć certyfikat self-signed.

    Bądź da się znaleźć na przykład darmowe certyfikaty SSL ważne przez rok podpisane przez zaufane centrum certyfikacji (http://cert.startcom.org/).

  4. Michał "Bełdzio" Ławicki napisał(a):

    Dobrze wiedzieć:)

  5. phjr napisał(a):

    Co do banlisty: trzymanie jej w sesji spowoduje, że całkowicie straci ona efektywność – wystarczy, że przy każdym nowym połączeniu/próbie bot będzie korzystał z nowej sesji…

  6. Michał "Bełdzio" Ławicki napisał(a):

    Nie do końca :) Ja np. sesje mam oparte o baze danych + tak jak pisałem zapisujesz jakieś info, które identyfikuje danego usera np. IP :) po połączeniu obu czynników działa to całkiem znośnie :)

  7. netmare napisał(a):

    Koledze chyba chodziło o to, że jeśli limit niepoprawnych logowań będzie ustawiony na więcej niż 1, to każdorazowe wyczyszczenie ciastka przed logowaniem spowoduje ominięcie tego zabezpieczenia ;)

  8. Michał "Bełdzio" Ławicki napisał(a):

    Tyle, że ilość niepoprawnych logowań zapisana jest z bazie danych, a nie w ciachu.

  9. Nitro napisał(a):

    Przynajmniej wiem co oznacza no-cache :)

    A mam pytanie: Jeżeli poodwiedzam jakiś serwis to tworzy się w pasku adresu w historii długa lista linków typu: serwis.pl/?idz=mapa serwis.pl/?idz=zobacz&co=wroclaw itd.
    Czy no-cache "blokuje" wpisywanie się takich linków i pozwala na przetrzymanie tylko jednego linku czyli serwis.pl?

    W sprawie certów SSL. Jeżeli robimy sami to przeglądarka będzie krzyczeć że nasz cert nie jest zaufany. Dlaczego? Bo nie ma podpisu wystawcy w naszej lokalnej "bazie podpisów". Co zrobić? Dwa razy na cert, dać na tak i mieć spokój, chyba że się do czegoś innego przyczepi. Mi się udało wystawić cert-myself na 33lat! I chyba to maksimum.

    Pozdrawiam

Trackbacks & Pingbacks

  1. Między neuronami a bitami » Blog Archive » Parę słów o szyfrowaniu i bezpieczeństwie

    […] należy powyłączać, komu co pozwolić opisano tutaj.  Jeśli nie używamy HTTPS (SSL),  to dane są przesyłane jawnie, czyli login i hasło można […]

Dodaj komentarz