Gdy atakujący obierają za cel formularze, nie wypełniają ich tak jak zwykli użytkownicy. Zamiast tego wysyłają kod, który ma włamać się do Twoich systemów albo wykraść dane. Mogą przesłać JavaScript uruchamiany w przeglądarkach odwiedzających, polecenia SQL niszczące bazę danych albo szkodliwą treść. Walidacja i sanityzacja danych to zabezpieczenia, które zatrzymują takie ataki.
Czego się dowiesz: czym są walidacja i sanityzacja danych, czym się różnią, jak działają ataki injection, jakie zabezpieczenia sprawdzają się dla różnych typów danych i jak wdrożyć je w swoich formularzach.
Czym jest walidacja danych?
Walidacja danych to sprawdzanie, czy dane przesłane w formularzu mają oczekiwany format i spełniają Twoje wymagania. To pierwsza linia obrony przed szkodliwymi danymi.
Walidacja odpowiada na pytania: czy to adres e-mail, czy przypadkowy tekst, czy to liczba, czy słowo, czy pole jest puste, choć nie powinno być, i czy odwiedzający wpisał coś, co ma sens w tym polu, czy raczej coś podejrzanego.
Przykłady tego, co sprawdza walidacja:
- Pole e-mail powinno zawierać znak @ i domenę
- Pole numeru telefonu powinno zawierać tylko cyfry i myślniki
- Pole liczbowe nie powinno zawierać liter
- Pole wymagane nie powinno być puste
- Pole hasła powinno spełniać minimalną długość
Walidacja odbywa się w dwóch miejscach. Na urządzeniu odwiedzającego nazywamy ją walidacją po stronie klienta. Na Twoim serwerze nazywamy ją walidacją po stronie serwera. Walidacja po stronie klienta od razu informuje odwiedzających o pomyłce. Walidacja po stronie serwera naprawdę chroni przed atakami, bo atakujący mogą ominąć kontrole po stronie klienta.
Czym jest sanityzacja danych?
Sanityzacja to usuwanie lub unieszkodliwianie wszystkiego, co niebezpieczne, w danych od użytkownika, zanim je zapiszesz lub przetworzysz. Nawet jeśli dane przejdą walidację, nadal mogą zawierać kod lub znaki stworzone, by wyrządzić szkodę.
Przykłady tego, co robi sanityzacja:
- Usuwa z pól tekstowych znaczniki HTML, takie jak `<script>` i `<img>`
- Usuwa znaki specjalne SQL, których można użyć do włamania do bazy danych
- Zamienia znaki specjalne tak, by były traktowane jak tekst, a nie kod
- Ogranicza długość danych, aby zapobiec atakom typu buffer overflow
Walidacja i sanityzacja działają razem, ale służą do różnych celów. Walidacja sprawdza, czy dane mają właściwy format. Sanityzacja usuwa wszystko, co niebezpieczne, nawet gdy format jest formalnie poprawny.
Jak działają ataki injection
SQL injection
Atak SQL injection ma miejsce, gdy atakujący wpisuje kod SQL w pole formularza. Jeśli kod Twojego formularza nie sanityzuje tych danych, kod SQL zostanie wykonany w Twojej bazie danych.
Przykład: formularz logowania prosi o adres e-mail. Zamiast swojego adresu atakujący wysyła:
' OR '1'='1 Jeśli formularz tego nie sanityzuje, Twój kod może uruchomić zapytanie SQL, które wygląda tak:
SELECT * FROM users WHERE email = '' OR '1'='1' Fragment `OR '1'='1'` sprawia, że warunek jest zawsze prawdziwy, więc zapytanie zwraca wszystkich użytkowników, a nie tylko tego z danym adresem. Atakujący ominął w ten sposób system logowania.
Cross-Site Scripting (XSS)
Atak XSS ma miejsce, gdy atakujący wysyła kod JavaScript w polu formularza. Jeśli formularz nie sanityzuje tego kodu i go zapisze, JavaScript uruchomi się w przeglądarkach wszystkich, którzy później zobaczą te dane.
Przykład: formularz komentarzy przyjmuje komentarze użytkowników. Atakujący wysyła:
<script>alert('hacked')</script> Jeśli to nie zostanie zsanityzowane i trafi do bazy danych, gdy ktokolwiek otworzy sekcję komentarzy, JavaScript się uruchomi i pokaże alert. Groźniejsza wersja mogłaby wykraść pliki cookie, przekierować odwiedzających na stronę phishingową albo wyciągnąć dane z formularza.
Command injection
Jeśli dane z Twojego formularza trafiają do poleceń systemowych (zdarza się to w niektórych systemach zaplecza), atakujący może wstrzyknąć polecenia systemu operacyjnego.
Przykład: pole formularza jest użyte w poleceniu takim jak:
ffmpeg -i $filename output.mp4 Jeśli `$filename` nie jest zsanityzowane, a atakujący wyśle `;rm -rf /`, polecenie zmieni się w:
ffmpeg -i ;rm -rf / output.mp4 Polecenie `rm -rf /` uruchamia się i usuwa pliki z systemu. Dlatego polecenia systemowe nigdy nie powinny dostawać niezsanityzowanych danych od użytkownika.
Walidacja i sanityzacja dla różnych typów danych
Adresy e-mail
Walidacja: sprawdź, czy dane pasują do wzorca adresu e-mail (coś w rodzaju tekst@domena.rozszerzenie). Upewnij się, że zawierają tylko dozwolone znaki.
Sanityzacja: usuń znaczniki HTML i znaki specjalne. Zostaw tylko litery, cyfry, kropki, myślniki i znak @.
Numery telefonów
Walidacja: sprawdź, czy zawierają tylko cyfry, myślniki, nawiasy i spacje. Zweryfikuj, czy długość jest właściwa dla oczekiwanego kraju.
Sanityzacja: usuń wszystkie znaki nienumeryczne poza myślnikami i nawiasami. W razie potrzeby usuń początkowe zera lub spacje.
Pola tekstowe (komentarze, imiona i nazwiska, adresy)
Walidacja: sprawdź, czy pole nie jest puste i czy długość jest rozsądna (nie miliony znaków).
Sanityzacja: usuń lub zamień znaczniki HTML, JavaScript i znaki specjalne SQL. Zostaw tylko zwykły tekst i podstawową interpunkcję.
Liczby i kwoty
Walidacja: sprawdź, czy dane są liczbą. W przypadku cen lub ilości sprawdź, czy jest to liczba dodatnia.
Sanityzacja: usuń wszystkie znaki nienumeryczne. W razie potrzeby zaokrąglij do właściwej liczby miejsc po przecinku.
Hasła
Walidacja: sprawdź minimalną długość (co najmniej 8 znaków) i opcjonalnie wymagaj mieszanki wielkich i małych liter, cyfr oraz symboli.
Sanityzacja: nie usuwaj znaków z haseł i nie zmieniaj ich. Powinny być przechowywane dokładnie w takiej postaci (jako hash, nigdy jawnym tekstem). Jeśli usuniesz znaki z hasła, użytkownicy nie będą mogli się zalogować.
Przesyłanie plików
Walidacja: sprawdź, czy typ pliku jest taki, jakiego oczekujesz (np. tylko pliki PDF, tylko obrazy). Sprawdź, czy rozmiar pliku nie jest zbyt duży.
Sanityzacja: zmień nazwę pliku, aby atakujący nie mogli użyć specjalnych nazw. Przeskanuj plik pod kątem złośliwego oprogramowania. Przechowuj go poza katalogiem głównym serwisu, aby nie dało się go wykonać jako kodu.
Jak wdrożyć walidację i sanityzację
Po stronie klienta (w przeglądarce)
Użyj atrybutów walidacji HTML5, aby od razu informować odwiedzających:
<input type="email" name="email" required> <input type="tel" name="phone" pattern="[0-9]{10}"> <input type="number" name="age" min="0" max="120"> Dzięki temu wychwycisz oczywiste pomyłki i poprawisz wygodę użytkowania. Walidację po stronie klienta można jednak ominąć, więc sama w sobie nie jest zabezpieczeniem.
Po stronie serwera (na Twoim serwerze)
Tu dzieje się bezpieczeństwo. Kod zaplecza musi zwalidować i zsanityzować każdą porcję danych:
// Przykład w pseudokodzie if (email does not match email pattern) { reject the submission } // Usuń znaczniki HTML sanitized_comment = remove_html_tags(comment_text) // Zamień znaki specjalne na potrzeby bazy danych safe_name = escape_sql_characters(user_name) // Dopiero potem zapisz dane store_in_database(safe_name, sanitized_comment) Używaj zapytań parametryzowanych w bazach danych
Najlepszą obroną przed SQL injection są zapytania parametryzowane (zwane też prepared statements). Zamiast wstawiać dane od użytkownika bezpośrednio do zapytania SQL, używasz symboli zastępczych i przekazujesz dane osobno:
// Źle (podatne): query = "SELECT * FROM users WHERE email = '" + email + "'" // Dobrze (bezpieczne): query = "SELECT * FROM users WHERE email = ?" execute(query, [email]) Przy zapytaniach parametryzowanych parser SQL wie, że dane od użytkownika to dane, a nie kod. Nawet jeśli atakujący wyśle kod SQL, zostanie on potraktowany jak zwykły tekst.
Korzystaj z bibliotek i frameworków
Nie pisz kodu sanityzacji od zera. Użyj sprawdzonych bibliotek stworzonych do tego celu. W PHP użyj htmlspecialchars() albo biblioteki takiej jak HTML Purifier. W Pythonie użyj modułu `html` albo biblioteki takiej jak bleach. W Node.js użyj `express-validator` lub podobnej. Te biblioteki są przetestowane i aktualizowane pod kątem nowych typów ataków.
Częste błędy w walidacji i sanityzacji
Walidacja tylko po stronie klienta. Walidacja po stronie klienta służy wygodzie użytkownika, nie bezpieczeństwu. Atakujący może ją ominąć. Musisz walidować także na serwerze.
Czarna lista niebezpiecznych znaków zamiast białej listy bezpiecznych. Jeśli próbujesz blokować SQL injection przez usuwanie średników i cudzysłowów, atakujący znajdą sposób, by to obejść. Zamiast tego dopuść na białej liście znaki, których oczekujesz (dla numerów telefonów tylko cyfry i myślniki), a wszystko inne odrzuć.
Ufanie typowi danych pola formularza. Jeśli masz pole liczbowe, przeglądarka wysyła tekst, który wygląda jak liczba. Serwer nadal musi sprawdzić, czy to faktycznie liczba, zanim jej użyje. Nigdy nie zakładaj, że typ danych jest poprawny.
Zapominanie o sanityzacji danych, które są wyświetlane. Nawet jeśli dane są zapisane bezpiecznie, wyświetlenie ich na stronie bez zamiany znaków HTML pozwala atakującym wstrzyknąć kod, który uruchomi się w przeglądarkach odwiedzających oglądających te dane.
Sanityzacja w złej kolejności. Najpierw waliduj (czy to właściwy format?), potem sanityzuj (czy to bezpieczne?). Jeśli najpierw zsanityzujesz, a dopiero potem zwalidujesz, możesz odrzucić dane, które faktycznie były bezpieczne.
Co WEMASY robi w zakresie walidacji danych
WEMASY automatycznie waliduje pola formularza na podstawie wybranego typu pola. Pola e-mail są sprawdzane pod kątem poprawnego formatu adresu. Pola liczbowe są sprawdzane pod kątem wartości liczbowej. Pola wymagane są sprawdzane pod kątem zawartości przed wysłaniem. Po stronie serwera WEMASY sanityzuje wszystkie dane, usuwając HTML, JavaScript i inny niebezpieczny kod, zanim zapisze zgłoszenia. Ty ustawiasz, jakie pola zbierać, a WEMASY zajmuje się walidacją i sanityzacją w tle.
Sprawdź, jakie funkcje formularzy są w Twoim pakiecie, na stronie z cennikiem.