Przejdź do treści
HexaTransfer
Wróć do bloga
Szyfrowanie i bezpieczenstwo

Nagłówki bezpieczeństwa dla aplikacji webowych: kompletny przewodnik

Skonfiguruj niezbędne nagłówki bezpieczeństwa dla aplikacji transferowej. CSP, HSTS, X-Frame-Options przeciw typowym atakom webowym.

Nagłówki bezpieczeństwa to pola odpowiedzi HTTP, które informują przeglądarki, jak ograniczać zachowanie strony. Dla aplikacji do transferu plików wykonującej szyfrowanie AES-256-GCM po stronie klienta sześć nagłówków ma kluczowe znaczenie: Strict-Transport-Security wymuszający HTTPS, Content-Security-Policy blokujący wstrzykiwanie skryptów, X-Frame-Options chroniący przed clickjackingiem, Referrer-Policy zapobiegający wyciekom fragmentów URL, Permissions-Policy wyłączający nieużywane API przeglądarki oraz Cross-Origin-Opener-Policy izolujący kontekst przeglądania. Prawidłowa konfiguracja tych nagłówków blokuje 80% praktycznych ataków po stronie klienta bez zmiany jakiejkolwiek linii JavaScript.

HSTS i lista preload

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload nakazuje przeglądarkom, by przez dwa lata nigdy nie łączyły się przez zwykłe HTTP. Dyrektywa preload kwalifikuje domenę do listy HSTS preload Chrome'a (hstspreload.org), dostarczanej razem z przeglądarką — nawet pierwsze żądanie do domeny odbywa się przez HTTPS, eliminując okno podatności na atak MITM. Zgłoszenie jest jednostronne; usunięcie z listy może trwać miesiącami. Należy przetestować konfigurację z wartością max-age=300 przez kilka dni. Usługa transferu plików bez preload HSTS pozostaje o jeden przejęty DNS od wyświetlenia fałszywego formularza przesyłania.

Content Security Policy, która faktycznie działa

CSP jest najtrudniejszym nagłówkiem do wdrożenia i zarazem najbardziej wartościowym. Rygorystyczna polityka dla aplikacji transferowej wygląda następująco: default-src 'none'; script-src 'self' 'wasm-unsafe-eval'; connect-src 'self' https://upload.hexatransfer.com; style-src 'self'; img-src 'self' data:; font-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'. Żadnych skryptów inline, żadnego eval z wyjątkiem wasm, żadnych połączeń do zewnętrznych serwisów. Należy przenieść wszystkie inline handlery zdarzeń do addEventListener w zewnętrznych plikach. Dyrektywa 'wasm-unsafe-eval' jest wymagana przez libsodium.js — bez niej Argon2id nie zainicjuje się.

Subresource Integrity przy każdym bundlu

Jeśli JavaScript ładuje się z CDN-a, takiego jak jsDelivr lub unpkg, do każdego tagu script należy dodać atrybut integrity="sha384-...". Przeglądarka odmawia uruchomienia skryptów, których hash nie zgadza się z deklarowanym — przejęty CDN nie może cicho wstrzyknąć zmodyfikowanego bundla. Dla skryptów hostowanych we własnej domenie SRI jest mniej krytyczny, ale wciąż uzasadniony. SRI należy łączyć z dyrektywą CSP require-sri-for script style (przestarzałą, ale nadal obsługiwaną przez Chrome) lub egzekwować ją przez pipeline budowania. HexaTransfer publikuje hashe dla każdego wydania, umożliwiając ręczną weryfikację wymagającym użytkownikom.

X-Frame-Options i frame-ancestors

Ataki clickjacking polegają na załadowaniu strony przesyłania w przezroczystym iframe ponad inną stroną, nakłaniając użytkownika do kliknięcia „wyślij" na pliku, którego nie chciał udostępnić. X-Frame-Options: DENY blokuje wszelkie osadzanie w ramkach; nowoczesnym odpowiednikiem jest Content-Security-Policy: frame-ancestors 'none'. Należy wysyłać oba nagłówki — starsze przeglądarki respektują tylko starszy nagłówek, nowsze preferują CSP. Nie należy stosować wartości SAMEORIGIN w aplikacji transferowej — nie ma uzasadnionego powodu, by osadzać interfejs przesyłania z innej strony.

Referrer-Policy przeciw wyciekom fragmentów URL

Przeglądarki domyślnie usuwają fragmenty URL (część #klucz=..., w której znajduje się klucz deszyfrowania) z nagłówków Referer, ale część ścieżki wciąż może wyciekać. Referrer-Policy: no-referrer blokuje wszelkie informacje o źródle żądania — brak nagłówka Referer w linkach wychodzących, brak wycieków cross-origin, brak profilowania URL przez zewnętrzne systemy śledzenia. Dla strony pobierania pod adresem /d/7Kj9xQmN2vP8rBwLsE4fT#k=abc uniemożliwia to wyciek sluga do jakiejkolwiek zewnętrznej domeny, do której użytkownik przejdzie. Nagłówek należy ustawiać globalnie przez konfigurację serwera, nie polegając na atrybucie rel="noreferrer" per link.

Permissions-Policy — ochrona w głąb

Jeśli aplikacja nie korzysta z kamery, mikrofonu, geolokalizacji ani USB, należy je explicite wyłączyć: Permissions-Policy: camera=(), microphone=(), geolocation=(), usb=(), bluetooth=(), accelerometer=(), magnetometer=(), gyroscope=(), payment=(). XSS, który przedostał się przez CSP, nadal nie będzie mógł włączyć kamery czy nagrywać użytkownika. Ten nagłówek jest tani we wdrożeniu, nie wpływa na UX w przepływie transferu plików i sygnalizuje audytorom bezpieczeństwa, że kwestia izolacji zasobów została przemyślana.

Nagłówki izolacji cross-origin

Dostęp do liczników wysokiej rozdzielczości i SharedArrayBuffer — potrzebnych niektórym implementacjom kryptografii wasm — wymaga izolacji cross-origin za pomocą Cross-Origin-Opener-Policy: same-origin oraz Cross-Origin-Embedder-Policy: require-corp. Nagłówki te zapobiegają również atakom kanałem bocznym typu Spectre, które mogłyby wykradać klucze AES z sąsiednich źródeł. Kompromis polega na tym, że osadzone zasoby zewnętrzne (filmy YouTube, Stripe checkout) przestają działać, chyba że serwują nagłówek Cross-Origin-Resource-Policy: cross-origin. Dla dedykowanej aplikacji transferowej bez żadnych osadzeń zewnętrznych izolacja jest bezkosztowa.

Cache-Control dla wrażliwych stron

Strona potwierdzenia pobierania może wyświetlać krótkotrwały klucz deszyfrowania lub token sesji. Należy zapobiec jej buforowaniu: Cache-Control: no-store, must-revalidate oraz Pragma: no-cache. Samo no-cache jest niewystarczające — pozwala na rewalidację z serwerem źródłowym, a więc buforowanie nadal zachodzi. Dla bundla JavaScript strony przesyłania zasada jest odwrotna: długi max-age z nazwami plików zawierającymi hash zawartości (/js/main-a7b3c9.js), by cache CDN działał bez problemów z inwalidacją. Nagłówki należy stosować precyzyjnie według ścieżek.

X-Content-Type-Options i MIME sniffing

X-Content-Type-Options: nosniff uniemożliwia przeglądarkom zgadywanie typów MIME na podstawie zawartości. Bez tego nagłówka plik .txt przesłany przez atakującego, zawierający <script>, mógłby być renderowany jako HTML przy serwowaniu go z powrotem. Dla usługi transferowej serwującej pliki kontrolowane przez użytkowników należy połączyć nosniff z nagłówkiem Content-Disposition: attachment; filename="...", by przeglądarka pobierała plik zamiast go renderować. Nazwy plików należy walidować po stronie serwera pod kątem path traversal (../../../etc/passwd) — nie należy ufać metadanym przesłanego pliku do czegokolwiek poza wyświetlaniem.

Monitorowanie i raporty CSP

CSP należy najpierw wdrożyć w trybie report-only, przez tydzień zbierać naruszenia pod adresem endpointu report-uri, naprawić uzasadnione problemy, a następnie przełączyć na tryb wymuszania. Endpoint raportowania odbiera POST-y JSON opisujące każde naruszenie: zablokowany URI, naruszona dyrektywa, plik źródłowy, numer linii. Usługi takie jak Report URI lub własna instancja Sentry gromadzą te dane. Przegląd należy przeprowadzać co tydzień — prawdziwe ataki ujawniają się jako nieznane wcześniej blokowane URI.

Ocena wyników

Produkcyjny URL należy sprawdzić przez securityheaders.com i Mozilla Observatory. Ocena A lub A+ nie oznacza perfekcji, ale jest minimalnym standardem. Większość konkurencyjnych usług transferu plików uzyskuje ocenę B lub gorszą, bo zapominają o Permissions-Policy lub zezwalają na 'unsafe-inline' w CSP. Mała usługa może z łatwością wyprzedzić wynik nagłówków bezpieczeństwa WeTransfera — nagłówki nic nie kosztują, a posiadanie rygorystycznej CSP od początku znacznie skraca rozmowy z audytorami SOC 2.

Wypróbuj na hexatransfer.com — bezpłatnie, bez konta, do 10 GB.

Wysyłaj duże pliki bezpiecznie z szyfrowaniem end-to-end

Przesyłaj pliki do 10 GB za darmo z szyfrowaniem end-to-end. Bez rejestracji. Twoje pliki są szyfrowane w przeglądarce przed przesłaniem — nikt inny nie może ich odczytać.

Wyślij plik