Chybí X-Content-Type-Options

Co to je

Hlavička X-Content-Type-Options: nosniff řekne prohlížeči „respektuj Content-Type, nehádej ho podle obsahu souboru“. Bez ní prohlížeče (zejména Internet Explorer historicky, dnes i další) zkoumají prvních pár bajtů a rozhodují samy.

Proč je to problém

Standardní scénář — uživatel nahraje na váš web obrázek. Útočník místo skutečného obrázku nahraje soubor cat.jpg, který uvnitř obsahuje HTML s <script>. Server ho rozumně označí jako image/jpeg. Prohlížeč ale bez nosniff zkoumá obsah, vidí HTML, a ten cat.jpg spustí jako stránku. Uploaded XSS.

Druhý scénář — CSS soubor, do kterého útočník dostal HTML, prohlížeč začne „rozumně“ renderovat. nosniff tomuhle dělá konec.

Jak to opravit

Triviální. Jediná hodnota je 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 → přidat header.

Co se může pokazit

Prakticky nic. nosniff jen vynucuje správné Content-Type — pokud váš server pro .css soubory posílá Content-Type: text/css, je to v pořádku. Problém by nastal, jen kdyby váš server posílal CSS s Content-Type: text/plain — pak by ho prohlížeč přestal renderovat. Pokud na to narazíte, opravujete vlastní MIME mapping, ne hlavičku.

Ověření

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

Reference