Walidacja danych wejściowych i wstrzyknięcia
Każda wartość przychodząca z zewnątrz, pole formularza, parametr zapytania, nagłówek, przesłany plik czy adres URL, który pobierasz, jest wrogiem, dopóki nie udowodni inaczej. Wstrzyknięcie następuje, gdy taka wartość jest traktowana jak kod lub struktura, a nie jak dane.
Lista kontrolna
- Zawsze używaj zapytań parametryzowanych. Nigdy nie buduj SQL przez sklejanie ciągów znaków. Używaj związanych parametrów albo ORM, który wiąże je za Ciebie. To zamyka SQL injection. Ta sama zasada dotyczy NoSQL i poleceń powłoki.
- Escapuj wyjście zależnie od kontekstu. Polegaj na szablonowaniu lub frameworku UI, który domyślnie escapuje (na przykład React). Bardzo uważaj na każdy mechanizm "renderuj surowy HTML". Tędy wkrada się cross-site scripting (XSS).
- Waliduj względem listy dozwolonych, a nie listy zabronionych. Zdefiniuj, jak wygląda poprawna wartość, i odrzucaj wszystko inne, zamiast próbować blokować złe dane.
- Chroń żądania wysyłane przez serwer (SSRF). Jeśli serwer pobiera adres URL podany przez użytkownika, waliduj go i blokuj wewnętrzne zakresy oraz adres metadanych chmury (169.254.169.254). Stosuj ścisłą walidację hosta i przypinaj DNS, aby przeciwdziałać rebindingowi DNS.
- Nigdy nie deserializuj niezaufanych danych do kodu. Unikaj pickle, natywnej deserializacji Javy lub PHP i podobnych mechanizmów na bajtach kontrolowanych przez atakującego. Uruchamiają one kod.
- Zabezpiecz przesyłanie plików. Weryfikuj rzeczywistą zawartość (magic bytes), a nie tylko rozszerzenie lub zadeklarowany typ. Wymuszaj twardy limit rozmiaru. Przechowuj pliki poza katalogiem webowym, pod losową lub opartą na identyfikatorze nazwą, nigdy pod nazwą podaną przez użytkownika. Serwuj je z poprawnym typem treści i
X-Content-Type-Options: nosniff. Skanuj je pod kątem złośliwego oprogramowania, jeśli możesz. - Waliduj ciała żądań względem schematu. Odrzucaj nieznane pola zamiast je przepuszczać (zob. mass assignment w API i żądaniach).
Jak testować
- Wpisz
' OR 1=1 --,<script>alert(1)</script>i${7*7}w każde pole i potwierdź, że są zapisane i wyświetlone jako dosłowny tekst. - Skieruj każde pole URL na
http://169.254.169.254/oraz nahttp://localhost/. - Prześlij plik HTML przemianowany na
.pngi potwierdź, że został odrzucony lub obsłużony jako nieszkodliwy.