Walidacja i sanityzacja danych oraz ochrona przed atakami injection

Dowiedz się, jak walidacja i sanityzacja danych chronią formularze przed atakami injection i co sprawia, że dane z formularza są bezpieczne.

Wersja robocza

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.

Najczęściej zadawane pytania

Czy mogę użyć WAF (Web Application Firewall) zamiast walidacji?
WAF może wychwycić część ataków injection, zanim dotrą do Twojego formularza, co jest pomocne. Nie zastępuje jednak walidacji i sanityzacji. WAF to druga linia obrony. Kod Twojego formularza nadal musi sam walidować i sanityzować dane. Połączenie WAF i walidacji danych daje wiele warstw ochrony.
Co, jeśli odwiedzający naprawdę musi wpisać znaki specjalne?
Znaki specjalne, takie jak apostrofy, myślniki i ampersandy, są bezpieczne, jeśli poprawnie sanityzujesz dane. Ktoś może mieć na przykład nazwisko "O'Brien" albo "Anna-Maria". Można je bezpiecznie przyjąć, jeśli poprawnie zamienisz je dla bazy danych (za pomocą zapytań parametryzowanych) i przy wyświetlaniu (za pomocą zamiany znaków HTML). Chodzi o właściwą sanityzację, a nie o blokowanie tych znaków.
Czy walidować dane zarówno po stronie klienta, jak i serwera?
Tak. Walidacja po stronie klienta od razu informuje odwiedzających i poprawia wygodę (wiedzą o literówce przed wysłaniem). Walidacja po stronie serwera naprawdę chroni przed atakami. Używaj obu warstw. Strona klienta służy wygodzie. Strona serwera służy bezpieczeństwu.
Jaka jest różnica między zamianą znaków (escaping) a sanityzacją?
Zamiana znaków (escaping) zmienia niebezpieczne znaki tak, aby były traktowane jak zwykły tekst (na przykład zamienia < na <). Sanityzacja całkowicie usuwa niebezpieczną treść (na przykład wycina wszystkie znaczniki HTML). Escaping zachowuje dane, sanityzacja usuwa zagrożenie. Dla większości danych z formularzy sanityzacja (całkowite usunięcie znaczników) jest bezpieczniejsza niż escaping (zamiana).
Czy muszę martwić się atakami injection w formularzach tylko do odczytu?
Jeśli formularz tylko wyświetla informacje (niczego nie wysyła), nie ma podatności na injection. Jeśli jednak ten formularz kiedykolwiek wyświetla dane przesłane przez użytkowników, nadal musisz je sanityzować. Atakujący mógł wcześniej przesłać szkodliwy kod, a gdy go wyświetlisz, ten kod się uruchomi. Zawsze sanityzuj wszelkie dane przesłane przez użytkowników przed wyświetleniem, niezależnie od typu formularza.

Wykorzystaj to od razu
na własnej stronie.

Zacznij za darmo z WEMASY i zbuduj stronę w kilka minut.