X-Content-Type-Options to nagłówek odpowiedzi HTTP z dokładnie jedną prawidłową wartością: nosniff. Instruuje przeglądarkę, aby ściśle stosowała się do typu MIME podanego w nagłówku Content-Type i nigdy nie próbowała samodzielnie zgadywać typu zawartości. Zapobiega to klasie ataków wykorzystujących zachowanie MIME-type sniffing przeglądarek.
Spośród wszystkich nagłówków bezpieczeństwa X-Content-Type-Options jest najłatwiejszy do zrozumienia i wdrożenia. Wymaga jednej linii konfiguracji, nie ma złożonych dyrektyw i praktycznie nie ma powodu, by go nie używać. A jednak zaskakująco wiele witryn nadal go nie wysyła.
Czym jest MIME-type sniffing i dlaczego przeglądarki to robią
Aby zrozumieć, dlaczego ten nagłówek istnieje, pomocna jest trochę historii. We wczesnych dniach sieci wiele serwerów było źle skonfigurowanych i wysyłało nieprawidłowe nagłówki Content-Type. Serwer mógł podać plik HTML jako text/plain lub obraz jako application/octet-stream. Gdyby przeglądarki ściśle przestrzegały podanego typu, strony te byłyby wyrenderowane jako surowy tekst lub wywoływałyby pobieranie zamiast prawidłowego wyświetlania.
Aby to obejść, przeglądarki zaczęły "wąchać" rzeczywistą zawartość plików w celu określenia ich prawdziwego typu. Przeglądarka patrzyła na pierwsze bajty odpowiedzi, sprawdzała znane sygnatury (takie jak tagi <html>, nagłówki obrazów lub wzorce JavaScript) i nadpisywała typ podany przez serwer, jeśli treść wyglądała inaczej. Internet Explorer był pod tym względem szczególnie agresywny. Jeśli IE wykrył coś, co wyglądało jak HTML lub JavaScript w pliku serwowanym jako text/plain, ochoczo to renderował lub wykonywał.
To był rozsądny obejście dla źle skonfigurowanych serwerów, ale stworzył poważną lukę bezpieczeństwa.
Jak MIME sniffing umożliwia ataki
Oto konkretny scenariusz ataku wymierzonego w witrynę WordPress z uploadem plików:
Załóżmy, że Twoja witryna WordPress pozwala użytkownikom wgrywać zdjęcia profilowe. Twój handler uploadu sprawdza rozszerzenie pliku i pozwala tylko na .jpg, .png i .gif. Atakujący tworzy plik, który zaczyna się od prawidłowych nagłówków obrazu (pierwsze bajty wyglądają jak prawidłowy JPEG), ale zawiera kod JavaScript po nagłówku obrazu. Nazywa go avatar.jpg i wgrywa.
Twój serwer zapisuje plik i serwuje go z Content-Type: image/jpeg. Do tego momentu wszystko wygląda dobrze. Ale teraz atakujący linkuje do tego pliku ze strony, na przykład w poście na forum lub komentarzu, używając tagu script:
<script src="https://twojastrona.pl/uploads/avatar.jpg"></script>Bez X-Content-Type-Options przeglądarka stosująca MIME sniffing mogłaby spojrzeć na plik, zauważyć, że zawiera treść podobną do JavaScript, i wykonać go jako skrypt mimo content-type image/jpeg. JavaScript atakującego teraz działa w kontekście Twojej strony, z dostępem do ciasteczek i danych sesji Twoich odwiedzających.
Z nagłówkiem nosniff przeglądarka respektuje podany typ image/jpeg i odmawia wykonania pliku jako JavaScript. Atak się nie powiedzie.
MIME sniffing a uploady mediów WordPress
WordPress ma system uploadu mediów, który obsługuje wiele typów plików: obrazy, PDF-y, dokumenty, audio i wideo. Każdy jest serwowany z określonym typem MIME. Rdzeń WordPressa już w pewnym stopniu waliduje uploady (sprawdza typy plików względem dozwolonej listy i weryfikuje, czy zawartość pasuje do rozszerzenia), ale te kontrole nie są niezawodne.
Kilka czynników sprawia, że WordPress jest tu szczególnie istotny:
- Wiele punktów uploadu: biblioteka mediów, Gravity Forms, Contact Form 7, zdjęcia produktów WooCommerce, załączniki forum bbPress i wiele innych wtyczek obsługuje uploady plików. Każdy jest potencjalnym wejściem dla złośliwych plików.
- Treści generowane przez użytkowników: na witrynach z funkcjami członkowskimi lub społecznościowymi możesz pozwalać stosunkowo niezaufanym użytkownikom wgrywać pliki. Im więcej źródeł uploadu, tym ważniejsze, by przeglądarka traktowała pliki dokładnie tak, jak podano.
- Handlery uploadu wtyczek: nie wszystkie wtyczki walidują uploady tak starannie jak rdzeń WordPressa. Źle napisana wtyczka może akceptować pliki z niepasującymi typami, tworząc dokładnie warunki, które wykorzystują ataki MIME sniffing.
- Środowiska shared hosting: w shared hostingu pliki z innych witryn na tym samym serwerze mogą być serwowane z nieprawidłowymi nagłówkami. Dyrektywa
nosniffdodaje warstwę obronną niezależnie od jakości konfiguracji serwera.
Najprostszy nagłówek bezpieczeństwa do wdrożenia
Dodanie X-Content-Type-Options zajmuje jedną linię. Nie ma dyrektyw do wyboru, wartości do dostrojenia ani ryzyka zepsucia funkcjonalności. W przeciwieństwie do CSP (które może zepsuć inline scripty), HSTS (które może Cię zablokować, jeśli certyfikat wygaśnie) lub Referrer-Policy (które może wpłynąć na analitykę), X-Content-Type-Options praktycznie nie ma wad.
Dla Apache (.htaccess lub virtual-host config):
Header always set X-Content-Type-Options "nosniff"Dla Nginx:
add_header X-Content-Type-Options "nosniff" always;Przez PHP w WordPressie:
add_action('send_headers', function() {
header('X-Content-Type-Options: nosniff');
});WordPress sam wysyła X-Content-Type-Options: nosniff dla stron administracyjnych i odpowiedzi REST API od wersji 4.8. Jednak strony frontendowe większości instalacji WordPress nie zawierają tego nagłówka, chyba że dodasz go na poziomie serwera lub przez wtyczkę bezpieczeństwa.
Jak nowoczesne przeglądarki radzą sobie z MIME sniffingiem
Zachowanie przeglądarek znacznie się poprawiło na przestrzeni lat. Nowoczesne wersje Chrome, Firefox, Safari i Edge są znacznie mniej agresywne z MIME sniffingiem niż przeglądarki z czasów Internet Explorera. Chrome na przykład już blokuje skrypty z typem MIME innym niż script w wielu sytuacjach, nawet bez nagłówka nosniff.
Jednak nadal istnieją edge cases, w których sniffing występuje, a starsze przeglądarki mogą być nadal podatne. Nagłówek nosniff daje jasną, ostateczną instrukcję, która usuwa wszelką niejednoznaczność. To dobra praktyka niezależnie od tego, jakie przeglądarki używają Twoi odwiedzający.
Interakcja z innymi nagłówkami bezpieczeństwa
X-Content-Type-Options dobrze współpracuje z innymi nagłówkami bezpieczeństwa i nie ma żadnych konfliktów, o które trzeba się martwić:
- W połączeniu z CSP zapewnia obronę w głąb: CSP kontroluje, jakie źródła są dozwolone, podczas gdy
nosniffzapewnia, że pliki z dozwolonych źródeł są traktowane jako ich podany typ. - Z HSTS zapewniasz szyfrowane połączenia, a z
nosniffdodatkowo gwarantujesz integralność zawartości. - W przeciwieństwie do innych nagłówków,
nosniffnie wchodzi w interakcję z innymi nagłówkami ani ich nie nadpisuje. Jest czysto addytywny.
Co sprawdza InspectWP
InspectWP sprawdza, czy Twoja witryna WordPress wysyła nagłówek X-Content-Type-Options: nosniff. Ponieważ ten nagłówek ma tylko jedną prawidłową wartość i nie ma żadnej złożoności konfiguracyjnej, naprawdę nie ma powodu, by go brakowało. Jeśli na Twojej stronie go brakuje, jest to jeden z najszybszych zysków bezpieczeństwa, jakie możesz osiągnąć. Dodanie zajmuje mniej niż minutę i zapewnia znaczącą ochronę przed atakami zamieszania typów MIME, zwłaszcza na stronach obsługujących uploady plików.