Brak X-Content-Type-Options

Co to jest

Nagłówek X-Content-Type-Options: nosniff mówi przeglądarce „respektuj Content-Type, nie zgaduj go na podstawie zawartości pliku”. Bez niego przeglądarki (historycznie zwłaszcza Internet Explorer, dziś również inne) badają pierwsze kilka bajtów i decydują same.

Dlaczego to problem

Typowy scenariusz — użytkownik wgrywa na Twoją stronę obrazek. Atakujący zamiast prawdziwego obrazka wgrywa plik cat.jpg, który w środku zawiera HTML z <script>. Serwer rozsądnie oznacza go jako image/jpeg. Przeglądarka jednak bez nosniff bada zawartość, widzi HTML i ten cat.jpg uruchamia jako stronę. Uploaded XSS.

Drugi scenariusz — plik CSS, do którego atakujący wstrzyknął HTML, przeglądarka zaczyna „rozsądnie” renderować. nosniff kładzie temu kres.

Jak to naprawić

Trywialnie. Jedyna wartość to nosniff.

nginx:

add_header X-Content-Type-Options "nosniff" always;

Apache:

Header always set X-Content-Type-Options "nosniff"

WordPress (functions.php / mu-plugin):

add_action('send_headers', function () {
    header('X-Content-Type-Options: nosniff');
});

Cloudflare: Rules → Transform Rules → HTTP Response Header Modification → dodaj nagłówek.

Co może pójść nie tak

Praktycznie nic. nosniff tylko wymusza poprawny Content-Type — jeśli Twój serwer wysyła dla plików .css Content-Type: text/css, wszystko jest w porządku. Problem wystąpiłby tylko wtedy, gdyby Twój serwer wysyłał CSS z Content-Type: text/plain — wówczas przeglądarka przestałaby go renderować. Jeśli na to natrafisz, naprawiasz własne mapowanie MIME, a nie nagłówek.

Weryfikacja

curl -I https://example.cz | grep -i content-type-options

Źródła