Niezależnie od tego czy pracujemy jako specjaliści od bezpieczeństwa, developerzy czy testerzy, z protokołem HTTP i komunikacją w aplikacji mamy do czynienia na co dzień. Niniejszy artykuł został poświęcony podstawowym zagadnieniom związanym z protokołem HTTP. Elementy powiązane z jego szyfrowaną wersją zostały pominięte.
Żądania i odpowiedzi
Komunikację miedzy klientem a serwerem zaczyna klient, który przesyła do serwera żądanie (request). Następnie serwer wysyła do klienta odpowiedź (response). Requesty przesyłane za pośrednictwem przeglądarki możemy podglądnąć w zakładce network za pomocą narzędzi developerskich.

Szablon zarówno responsu jak i requesta jest z góry narzucony przez specyfikację protokołu. W związku z tym każdy z nich będzie wyglądał w podobny sposób. Przeanalizujmy główne części żądania poniżej.
GET /omowienie-ldap-oraz-ataku-ldap-injection/ HTTP/2
Host: bugspace.pl
Pierwsza z linijek żądania składa się z trzech części. Jest to kolejno:
GET
– wykorzystywana przez żądanie metoda,/omowienie-ldap-oraz-ataku-ldap-injection/
– w naszym przypadku względny adres URL. Warto pamiętać, że możemy w tym miejscu zdefiniować pełny adres URL,HTTP/2
– wersja używanego protokołu.
W drugiej linii znajduje się nagłówek Host, który przyjmuje wartość adresu URL. Kolejne części są nagłówkami dołączanymi przez przeglądarkę, które nie grają znaczenia w niniejszym artykule. Warto dodać, że w naszym przypadku żądanie powinno kończyć się dwoma pustymi liniami – pierwsza po nagłówku Host i druga po wszystkich nagłówkach. Koniec bieżącej linii nazywany jest CRLF i o podatności, która jest z nią związana będziecie mogli dowiedzieć się więcej z artykułów w przyszłości.
Jako odpowiedź otrzymaliśmy od serwera:
HTTP/2 200 OK
Ponownie możemy wyróżnić dwie części:
HTTP/2
– wersja używanego protokołu,200 OK
– status odpowiedzi serwera. O nim samym dowiecie się więcej z kolejnej sekcji.
Statusy odpowiedzi
W poprzedniej sekcji wspomnieliśmy o tym, że serwer zwraca status. Status jest niczym innym jak skróconą odpowiedzią serwera. Istnieje pięć typów odpowiedzi: informujące, potwierdzające, przekierowujące, informujące o błędzie po stronie serwera i informujące o błędzie po stronie klienta. Przeanalizujmy część dostępnych statusów.
201 Created
– Żądanie powiodło się, a w jego wyniku został utworzony nowy zasób. Jest to typowa odpowiedź wysyłana po żądaniach POST lub niektórych żądaniach PUT,301 Moved Permanently
– Adres URL żądanego zasobu został zmieniony na stałe. Nowy adres URL jest podawany w odpowiedzi,400 Bad Request
– Serwer nie może lub nie chce przetworzyć żądania z powodu czegoś, co jest postrzegane jako błąd klienta (np. nieprawidłowa składnia żądania, nieprawidłowe obramowanie wiadomości żądania lub zwodnicze kierowanie żądania),401 Unauthorized
– Chociaż standard HTTP określa „nieautoryzowany”, semantycznie odpowiedź ta oznacza „nieuwierzytelniony”. Oznacza to, że klient musi się uwierzytelnić, aby uzyskać żądaną odpowiedź,409 Too Many Requests
– Użytkownik wysłał zbyt wiele żądań w określonym czasie,500 Internal Server Error
– Serwer napotkał sytuację, z którą nie wie, jak sobie poradzić.
Pełna lista statusów wraz z ich opisami znajduje się w dokumentacji mozilli.
Metody HTTP
W poprzednim przykładzie analizowaliśmy jedynie żądania z użyciem metody GET. W RFC7231 możemy wyróżnić osiem metod. Są to: OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE oraz CONNECT. Inną metodą opisaną dopiero w RFC5789 jest PATCH.
GET
– odpowiada za pobieranie zawartości na stronie. Mogą to być zarówno zdjęcia, jak i reprezentacje danych w formacie JSON,POST
– przesyłanie danych na serwer,PUT
– edycja lub dodanie danych na serwer,DELETE
– usuwanie danych,HEAD
– robi to samo, co metoda GET, z tą różnicą, że nie zwraca treści wiadomości, a jedynie nagłówki,OPTIONS
– wskazuje obsługiwane przez serwer metody. Informacja ta nie zawsze musi być prawdziwa,TRACE
– wykonuje test pętli zwrotnej komunikatów wzdłuż ścieżki do zasobu docelowego,CONNECT
– tworzenie tunelu poprzez serwer proxy,PATCH
– aktualizacja danych.
Przesyłanie danych
Istnieje kilka sposobów na przekazywanie parametrów za pośrednictwem protokołu HTTP. Jest to szczególnie ważne w kontekście bezpieczeństwa, ponieważ właśnie w ten sposób dochodzi do jednych z najbardziej znanych nadużyć takich jak infekcje.
Adres URL
Pierwszym ze sposobów jest przekazywanie danych za pośrednictwem parametrów w adresie URL. Aby lepiej to zrozumieć, przyjrzyjmy się poniższemu żądaniowi.
GET /?s=myValue/ HTTP/2
Host: bugspace.pl
Jest to request przesłany na naszego bloga za pośrednictwem wyszukiwarki. Parametr s
odpowiedzialny jest za przefiltrowanie wszystkich postów blogowych, w których występuje fraza myValue
. Gdyby istniało więcej parametrów, byłyby one oddzielone od siebie znakiem &
. Jako przykład może posłużyć poniższy URL.
https://bugspace.pl?s=myValue&v2=myValue2
Istnieją znaki zastrzeżone, które nie mogą zostać bezpośrednio przesłane poprzez adres URL. Należy do nich np. @. Aby znak został przesłany, trzeba użyć kodowania URL. Zakodowany znak miałby postać %40
.
Metoda POST
Jak wiemy, metoda POST służy do przesyłania informacji o danym typie treści żądania. Jest on określany przez nagłówek Content-Type
, który może przyjąć wartość text/plain
, multipart/form-data
oraz application/x-www-form-urlencoded
. Aby dane w metodzie POST zostały przesłane, należy je zdefiniować w specjalnym miejscu nazywanym ciałem żądania (body). Znajduje się ono po wszystkich nagłówkach i oddzielone jest od nich pustą linią.
multipart/form-data
Przeanalizujmy przykład żądania multipart/form-data
.
POST /test HTTP/1.1
Host: foo.example
Content-Type: multipart/form-data;boundary="boundary"
--boundary
Content-Disposition: form-data; name="field1"
value1
--boundary
Content-Disposition: form-data; name="field2"; filename="example.txt"
value2
--boundary--
W żądaniach typu multipart/form-data
wartość jest przesyłana jako blok danych (ang. body part), przy czym każda część jest oddzielona ogranicznikiem (boundary). Jest to najczęściej losowa wartość o danej długości. Parametry są podane w nagłówku Content-Disposition
każdej z części.
application/x-www-form-urlencoded
W przypadku żądań application/x-www-form-urlencoded
jest prościej. Przekazywane parametry w sekcji body są, podobnie jak w przypadku przekazywanych parametrów URL, oddzielone od siebie znakiem &
. Przykład może stanowić poniższe żądanie.
POST /test HTTP/1.1
Host: foo.example
Content-Type: application/x-www-form-urlencoded
Content-Length: 27
field1=value1&field2=value2
To, o czym nie wspomnieliśmy wcześniej, to dołączony nagłówek Content-Length
, który wskazuje na długość ciała żądania.
Nagłówki HTTP
Istnieją dwa rodzaje nagłówków – odpowiedzi oraz żądań. Z drugim typem spotkaliśmy się na początku artykułu i był to nagłówek Host
. Nagłówki mają cel informacyjny, kontrolny oraz konfiguracyjny. Są dodatkowymi (poza bezpośrednio przesyłanymi) danymi używanymi do komunikacji między klientem a serwerem.
Przeanalizujmy kolejno część z dostępnych nagłówków.
Nagłówki żądań
Cookie
– wysyła ciasteczko na serwer,Accept
– rodzaje zasobów, które akceptuje klient w odpowiedzi od serwera,User-Agent
– identyfikacja użytej przez klienta przeglądarki,Accept-Language
– klient przesyła informację w jakim języku preferuje odczyt strony.
Nagłówki odpowiedzi
Set-Cookie
– serwer przesyła żądanie ustawienia ciasteczka,Location
– przekierowuje klienta na inny adres,Content-Type
– serwer informuje klienta, w jakim formacie i stronie kodowej wysyłany jest dokument.
Źródła
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
https://datatracker.ietf.org/doc/html/rfc2616#section-5.1.1
https://datatracker.ietf.org/doc/html/rfc5789#section-2
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST