HTTPQUERY
Русский

X-Content-Type-Options

Применение

MIME-сниффинг — это поведение браузера, при котором он изучает содержимое ответа и переопределяет объявленный Content-Type на основе шаблонов, найденных в теле ответа. Задуманный как удобство для неправильно настроенных серверов, MIME-сниффинг открывает брешь в безопасности: злоумышленник загружает файл, замаскированный под изображение, браузер распознаёт содержимое как HTML или JavaScript, и выполняется атака межсайтового скриптинга.

Заголовок X-Content-Type-Options закрывает эту брешь. Со значением nosniff браузер строго следует заголовку Content-Type и отказывается загружать ресурсы, у которых объявленный тип не соответствует ожидаемому. Для назначений типа «стиль» браузер блокирует ответ, если Content-Type не равен text/css. Для назначений типа «скрипт» браузер блокирует ответ, если Content-Type не является допустимым MIME-типом JavaScript.

Этот заголовок широко применяется как стандартная мера усиления безопасности и рекомендуется наряду с Content-Security-Policy и X-Frame-Options для эшелонированной защиты.

nosniff

Значение nosniff — единственное определённое значение. Установка этой директивы не даёт браузеру с помощью MIME-сниффинга отойти от объявленного Content-Type.

Пример

Сервер отдаёт ответ JSON API с отключённым MIME-сниффингом, гарантируя, что браузер обработает ответ строго как JSON:

Content-Type: application/json
X-Content-Type-Options: nosniff

CSS-файл, отдаваемый с правильным Content-Type и защитой от сниффинга, что не позволяет браузеру переинтерпретировать файл:

Content-Type: text/css
X-Content-Type-Options: nosniff

Диагностика

Ресурсы, заблокированные nosniff, порождают ошибки в консоли, где указывается несоответствие MIME-типа между объявленным Content-Type и типом, ожидаемым для назначения ресурса.

Скрипт заблокирован из-за несоответствия MIME-типа. Браузер записывает в журнал Refused to execute script from ’…’ because its MIME type (‘text/plain’) is not executable. Это происходит, когда сервер отправляет JavaScript-файл с Content-Type, отличным от допустимого MIME-типа JavaScript (text/javascript, application/javascript). Исправьте конфигурацию сервера. В nginx убедитесь, что в блоке http присутствует include mime.types;. В Apache проверьте, что в конфигурации или .htaccess есть AddType text/javascript .js.

CSS не применяется из-за неверного MIME-типа при nosniff. В консоли отображается Refused to apply style from ’…’ because its MIME type (‘text/html’) is not a supported stylesheet MIME type. Сервер отправляет CSS-файлы как text/html или text/plain вместо text/css. В nginx добавление types { text/css css; } или подключение стандартного файла mime.types устраняет это несоответствие. В Apache добавьте AddType text/css .css в конфигурацию сервера.

Сервер отправляет неверный Content-Type для статических файлов. Неправильно настроенные серверы, CDN или объектные хранилища (S3, GCS) часто отдают статические файлы как application/octet-stream или text/plain. Проверьте Content-Type каждого ресурса на вкладке Network в DevTools, выбрав запрос и изучив заголовки ответа. Для S3 задавайте метаданные ContentType при загрузке. Для ресурсов, отдаваемых через CDN, убедитесь, что источник возвращает правильный тип, поскольку большинство CDN передают Content-Type источника без изменений.

Диагностика заблокированных ресурсов в консоли DevTools. Откройте вкладку Console и отфильтруйте ошибки, связанные с MIME. Каждое сообщение о заблокированном ресурсе содержит URL, объявленный MIME-тип и ожидаемый тип. Сверьтесь с вкладкой Network: выберите заблокированный запрос, откройте панель Headers и проверьте заголовок ответа Content-Type. Исправление всегда заключается в корректировке Content-Type на сервере, а не в удалении заголовка nosniff.

Конфигурация

Применяйте nosniff ко всем ответам. Накладные расходы пренебрежимо малы, а защита охватывает скрипты, стили и другие подресурсы.

nginx:

add_header X-Content-Type-Options nosniff always;

Apache:

Header always set X-Content-Type-Options nosniff

IIS (web.config):

<code class="language-xml"><customHeaders>
  <add name="X-Content-Type-Options"
       value="nosniff" />
</customHeaders>