Dane wejściowe i wyjściowe

Ukończone

Najbardziej rozpowszechnioną słabością zabezpieczeń obecnych aplikacji jest nieprawidłowe przetwarzanie danych odbieranych ze źródeł zewnętrznych, a zwłaszcza danych wejściowych użytkownika. Zawsze należy dokładnie przyjrzeć się wszelkim danym wejściowym, aby upewnić się, że zweryfikowano je przed użyciem. Nieprzeanalizowanie danych wejściowych użytkownika pod kątem możliwych ataków może doprowadzić do utraty lub zagrożenia danych, podniesienia uprawnień lub nawet wykonania złośliwego kodu na komputerach innych użytkowników.

Najgorszym aspektem tej sytuacji jest fakt, że ten scenariusz można łatwo rozwiązać. W tej lekcji omówimy sposób traktowania danych po ich odebraniu, wyświetlania na ekranie i przechowywania ich do późniejszego użycia.

Dlaczego musimy walidować nasze dane wejściowe?

Załóżmy, że tworzysz interfejs umożliwiający użytkownikowi utworzenie konta w witrynie internetowej. Nasze dane profilowe zawierają nazwę, adres e-mail i pseudonim, który będziemy wyświetlać wszystkim, którzy odwiedzają witrynę. A co, jeśli nowy użytkownik tworzy profil i wprowadza pseudonim, który zawiera kilka poleceń SQL? Na przykład co zrobić, jeśli złośliwy użytkownik wprowadzi coś podobnego do następującego fragmentu:

Eve'); DROP TABLE Users;--

Jeśli bezrefleksyjne wstawimy tę wartość do bazy danych, potencjalnie może ona zmienić instrukcję SQL w celu wykonania poleceń, których absolutnie nie chcemy uruchamiać! Ten przykład jest określany jako atak „Wstrzyknięcia kodu SQL” i jest jednym z wielu typów programów wykorzystujących luki w zabezpieczeniach, które potencjalnie można wykonać, gdy dane wejściowe użytkownika nie są poprawnie obsługiwane. Co więc możemy zrobić, aby naprawić tę sytuację? W tej lekcji nauczysz się, kiedy należy walidować dane wejściowe, jak można kodować dane wyjściowe i jak tworzyć zapytania parametryczne (co rozwiązuje powyższy problem z programem wykorzystującym luki). Te techniki to trzy główne techniki obrony przed złośliwymi danymi wejściowymi wprowadzanymi do Twoich aplikacji.

Kiedy konieczna jest walidacja danych wejściowych?

Odpowiedź brzmi zawsze. Musisz walidować wszystkie dane wejściowe do Twojej aplikacji. Obejmuje to parametry w adresie URL, dane wejściowe od użytkownika, dane z bazy danych, dane z interfejsu API i wszystko, co jest przekazywane w przejrzysty sposób, że użytkownik może potencjalnie manipulować. Zawsze używaj podejścia do listy dozwolonych, co oznacza, że akceptujesz tylko "znane dobre" dane wejściowe, zamiast listy zablokowanych (gdzie w szczególności szukasz nieprawidłowych danych wejściowych), ponieważ nie można myśleć o pełnej liście potencjalnie niebezpiecznych danych wejściowych. Wykonaj tę pracę na serwerze, a nie po stronie klienta (lub oprócz po stronie klienta), aby upewnić się, że nie można obejść obrony. Traktuj wszystkie dane jako niezaufane i będziesz chronić się przed większością typowych luk w zabezpieczeniach aplikacji internetowych.

Jeśli używasz ASP.NET, platforma zapewnia doskonałą obsługę walidacji danych wejściowych po stronie klienta i serwera.

Jeśli używasz innej struktury internetowej, istnieje kilka świetnych technik sprawdzania poprawności danych wejściowych dostępnych w ściągawce weryfikacji danych wejściowych OWASP.

Zawsze używaj zapytań parametrycznych

Bazy danych SQL są często używane do przechowywania danych; Na przykład aplikacja może przechowywać informacje o profilu użytkownika w bazie danych. Nigdy nie należy tworzyć wbudowanych zapytań SQL lub innych baz danych w kodzie przy użyciu nieprzetworzonych danych wejściowych użytkownika i wysyłać je bezpośrednio do bazy danych; to zachowanie jest przepisem na awarię, jak widzieliśmy wcześniej.

Na przykład nie twórz kodu takiego jak poniższy wbudowany przykład SQL:

string userName = Request.QueryString["username"]; // receive input from the user BEWARE!
...
string query = "SELECT *  FROM  [dbo].[users] WHERE userName = '" + userName + "'";

W tym miejscu połączymy ze sobą ciągi tekstowe, aby utworzyć zapytanie, korzystając z danych wejściowych od użytkownika i generując dynamiczne zapytanie SQL, aby wyszukać użytkownika. I znowu, jeśli złośliwy użytkownik zrozumiał, że to robimy, lub po prostu próbował różnych stylów wejściowych, aby sprawdzić, czy istnieje luka w zabezpieczeniach, możemy doprowadzić do poważnej awarii. Zamiast tego lepiej użyć sparametryzowanych instrukcji SQL lub procedur składowanych, takich jak ta:

-- Lookup a user
CREATE PROCEDURE sp_findUser
(
@UserName varchar(50)
)

SELECT *  FROM  [dbo].[users] WHERE userName = @UserName

Dzięki tej metodzie można bezpiecznie wywołać procedurę z kodu, przekazując go userName do ciągu bez martwienia się o to, że jest traktowany jako część instrukcji SQL.

Zawsze koduj dane wyjściowe

Wszelkie dane wyjściowe, które przedstawiasz wizualnie lub w dokumencie, zawsze powinny być zakodowane i poprzedzone znakiem zmiany znaczenia. Może to chronić Cię w przypadku, gdy coś zostało pominięte w przebiegu oczyszczania lub kod przypadkowo generuje coś, co może być używane złośliwie. Ta zasada projektowania pozwala upewnić się, że wszystko jest wyświetlane jako dane wyjściowe i nie jest niezamierzenie interpretowane jako coś, co ma być wykonane, co jest inną, często spotykaną techniką ataku, określaną jako „użycie skryptów między witrynami” (XSS, Cross-Site Scripting).

Ponieważ zapobieganie atakom XSS jest częstym wymaganiem dotyczącym aplikacji, ta technika zabezpieczeń to kolejny obszar, w którym ASP.NET wykona pracę za Ciebie. Domyślnie wszystkie dane wyjściowe są już zakodowane. Jeśli używasz innej platformy internetowej, możesz zweryfikować opcje kodowania danych wyjściowych w witrynach internetowych za pomocą ściągawki OWASP XSS Prevention.

Podsumowanie

Oczyszczanie i walidacja danych wejściowych są konieczne do zapewnienia prawidłowości Twoich danych wejściowych oraz bezpiecznego korzystania z nich i ich przechowywania. Większość nowoczesnych środowisk internetowych oferuje wbudowane funkcje, które mogą zautomatyzować niektóre z tych prac. W dokumentacji preferowanego środowiska możesz sprawdzić, jakie funkcje ono oferuje. Najbardziej typowymi miejscami, w których to się dzieje, są aplikacje sieci Web. Należy jednak pamiętać, że inne typy aplikacji mogą zagrożone w tym samym stopniu. Nie należy zakładać, że bezpieczeństwo jest gwarantowane, tylko dlatego, że Twoja nowa aplikacja jest aplikacją klasyczną. Nadal musisz prawidłowo obsługiwać dane wejściowe użytkownika, aby upewnić się, że ktoś nie używa twojej aplikacji do uszkodzenia danych lub uszkodzenia reputacji firmy.

Sprawdź swoją wiedzę

1.

Które z następujących źródeł danych muszą być weryfikowane?

2.

Zapytania parametryczne (procedury składowane w języku SQL) to bezpieczny sposób komunikacji z bazą danych, ponieważ:

3.

Które z następujących danych muszą być zakodowane na wyjściu?