This site uses cookies for analytics. By continuing to browse this site, you agree to this use.
A JS Foundation Project

Require `Content-Type` HTTP response header with appropriate value

Require Content-Type HTTP response header with appropriate value (@sonarwhal/rule-content-type)

content-type warns against not serving resources with the Content-Type HTTP response header with a value containing the appropriate media type and charset for the response.

Why is this important?

Even though browsers sometimes ignore the value of the Content-Type header and try to sniff the content, it’s indicated to always send the appropriate media type and charset for the response as, among other:

What does the rule check?

The rule checks if responses include the Content-Type HTTP response header and its value contains the appropiate media type and charset for the response.

Examples that trigger the rule

Content-Type response header is not sent:

HTTP/... 200 OK

...

Content-Type response header is sent with an invalid value:

HTTP/... 200 OK

...
Content-Type: invalid
HTTP/... 200 OK

...
Content-Type: text/html;;;

Content-Type response header is sent with the wrong media type:

For /example.png

HTTP/... 200 OK

...
Content-Type: font/woff2

Content-Type response header is sent with an unofficial media type:

For /example.js

HTTP/... 200 OK

...
Content-Type: application/x-javascript; charset=utf-8

Content-Type response header is sent without the charset parameter for response that should have it:

For /example.html

HTTP/... 200 OK

...
Content-Type: text/html

Examples that pass the rule

For /example.png

HTTP/... 200 OK

...
Content-Type: image/png

For /example.js

HTTP/... 200 OK

...
Content-Type: text/javascript; charset=utf-8

How to configure the server to pass this rule

How to configure Apache

By default Apache maps certain filename extensions to specific media types, but depending on the Apache version that is used, some mappings may be outdated or missing.

Fortunately, Apache provides a way to overwrite and add to the existing media types mappings using the AddType directive. For example, to configure Apache to serve .webmanifest files with the application/manifest+json media type, the following can be used:

<IfModule mod_mime.c>
AddType application/manifest+json webmanifest
</IfModule>

The same goes for mapping certain filename extensions to specific charsets, which can be done using the AddDefaultCharset and AddCharset directives.

If you don’t want to start from scratch, below is a generic starter snippet that contains the necessary mappings to ensure that commonly used file types are served with the appropriate Content-Type response header, and thus, make your web site/app pass this rule.

# Serve resources with the proper media types (f.k.a. MIME types).
# https://www.iana.org/assignments/media-types/media-types.xhtml

<IfModule mod_mime.c>

# Data interchange

# 2.2.x+

AddType text/xml xml

# 2.2.x - 2.4.x

AddType application/json json
AddType application/rss+xml rss

# 2.4.x+

AddType application/json map

# JavaScript

# 2.2.x+

# See: https://html.spec.whatwg.org/multipage/scripting.html#scriptingLanguages.
AddType text/javascript js mjs


# Manifest files

# 2.2.x+

AddType application/manifest+json webmanifest
AddType text/cache-manifest appcache


# Media files

# 2.2.x - 2.4.x

AddType audio/mp4 f4a f4b m4a
AddType audio/ogg oga ogg spx
AddType video/mp4 mp4 mp4v mpg4
AddType video/ogg ogv
AddType video/webm webm
AddType video/x-flv flv

# 2.2.x+

AddType image/svg+xml svgz
AddType image/x-icon cur

# 2.4.x+

AddType image/webp webp


# Web fonts

# 2.2.x - 2.4.x

AddType application/vnd.ms-fontobject eot

# 2.2.x+

AddType font/woff woff
AddType font/woff2 woff2
AddType font/ttf ttf
AddType font/collection ttc
AddType font/otf otf


# Other

# 2.2.x+

AddType text/vtt vtt

</IfModule>

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

# Serve all resources labeled as `text/html` or `text/plain`
# with the media type `charset` parameter set to `utf-8`.
#
# https://httpd.apache.org/docs/current/mod/core.html#adddefaultcharset

AddDefaultCharset utf-8

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

# Serve the following file types with the media type `charset`
# parameter set to `utf-8`.
#
# https://httpd.apache.org/docs/current/mod/mod_mime.html#addcharset

<IfModule mod_mime.c>
AddCharset utf-8 .appcache \
.atom \
.css \
.js \
.json \
.manifest \
.map \
.mjs \
.rdf \
.rss \
.vtt \
.webmanifest \
.xml
</IfModule>

Note that:

  • The above snippet works with Apache v2.2.0+, but you need to have mod_mime enabled in order for it to take effect.

  • If you have access to the main Apache configuration file (usually called httpd.conf), you should add the logic in, for example, a <Directory> section in that file. This is usually the recommended way as using .htaccess files slows down Apache!

    If you don’t have access to the main configuration file (quite common with hosting services), add the snippets in a .htaccess file in the root of the web site/app.

How to configure IIS

By default IIS maps certain filename extensions to specific media types, but depending on the IIS version that is used, some mappings may be outdated or missing.

Fortunately, IIS provides a way to overwrite and add to the existing media types mappings using the <mimeMap> element under . For example, to configure IIS to serve .webmanifest files with the application/manifest+json media type, the following can be used:

<staticContent>
<mimeMap fileExtension="webmanifest" mimeType="application/manifest+json"/>
</staticContent>

The same element can be used to specify the charset. Continuing with the example above, if we want to use utf-8 it should be as follows:

<staticContent>
<mimeMap fileExtension="webmanifest" mimeType="application/manifest+json; charset=utf-8"/>
</staticContent>

If you don’t want to start from scratch, below is a generic starter snippet that contains the necessary mappings to ensure that commonly used file types are served with the appropriate Content-Type response header, and thus, make your web site/app pass this rule.

Note: the remove element is used to make sure we don’t use IIS defaults for the given extension.

<configuration>
<system.webServer>
<staticContent>
<!-- IIS doesn't set the charset automatically, so we have to override some
of the predefined ones -->

<!-- Data interchange -->
<mimeMap fileExtension=".json" mimeType="application/json; charset=utf-8"/>
<mimeMap fileExtension=".map" mimeType="application/json; charset=utf-8"/>
<mimeMap fileExtension=".rss" mimeType="application/rss+xml; charset=utf-8"/>
<mimeMap fileExtension=".xml" mimeType="text/xml; charset=utf-8"/>

<!-- JavaScript -->
<!-- https://html.spec.whatwg.org/multipage/scripting.html#scriptingLanguages -->
<mimeMap fileExtension=".js" mimeType="text/javascript; charset=utf-8"/>
<mimeMap fileExtension=".mjs" mimeType="text/javascript; charset=utf-8"/>

<!-- Manifest files -->
<mimeMap fileExtension=".appcache" mimeType="text/cache-manifest; charset=utf-8"/>
<mimeMap fileExtension=".webmanifest" mimeType="application/manifest+json; charset=utf-8"/>

<!-- Media files -->
<mimeMap fileExtension=".f4a" mimeType="audio/mp4"/>
<mimeMap fileExtension=".f4b" mimeType="audio/mp4"/>
<mimeMap fileExtension=".m4a" mimeType="audio/mp4"/>
<mimeMap fileExtension=".oga" mimeType="audio/ogg"/>
<mimeMap fileExtension=".ogg" mimeType="audio/ogg"/>
<mimeMap fileExtension=".spx" mimeType="audio/ogg"/>

<mimeMap fileExtension=".mp4" mimeType="video/mp4"/>
<mimeMap fileExtension=".mp4v" mimeType="video/mp4"/>
<mimeMap fileExtension=".mpg4" mimeType="video/mp4"/>
<mimeMap fileExtension=".ogv" mimeType="video/ogg"/>
<mimeMap fileExtension=".webm" mimeType="video/webm"/>
<mimeMap fileExtension=".flv" mimeType="video/x-flv"/>

<mimeMap fileExtension=".cur" mimeType="image/x-icon"/>
<mimeMap fileExtension=".ico" mimeType="image/x-icon"/>
<mimeMap fileExtension=".svg" mimeType="image/svg+xml; charset=utf-8"/>
<mimeMap fileExtension=".svgz" mimeType="image/svg+xml"/>
<mimeMap fileExtension=".webp" mimeType="image/webp"/>


<!-- Font files -->
<mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject"/>
<mimeMap fileExtension=".otf" mimeType="font/otf"/>
<mimeMap fileExtension=".ttc" mimeType="font/collection"/>
<mimeMap fileExtension=".ttf" mimeType="font/ttf"/>
<mimeMap fileExtension=".woff" mimeType="font/woff"/>
<mimeMap fileExtension=".woff2" mimeType="font/woff2"/>

<!-- Others -->
<mimeMap fileExtension=".css" mimeType="text/css; charset=utf-8"/>
<mimeMap fileExtension=".html" mimeType="text/html; charset=utf-8" />
<mimeMap fileExtension=".txt" mimeType="text/plain; charset=utf-8" />
<mimeMap fileExtension=".vtt" mimeType="text/vtt; charset=utf-8"/>
</staticContent>

<!-- This is needed only if you are serving .svgz images -->
<outboundRules>
<rule name="svgz-content-enconding" enabled="true">
<match serverVariable="RESPONSE_Content_Encoding" pattern=".*" />
<conditions>
<add input="{REQUEST_Filename}" pattern="\.svgz$" />
</conditions>
<action type="Rewrite" value="gzip" />
</rule>
</outboundRules>
</system.webServer>
</configuration>

Note that:

  • The above snippet works with IIS 7+.
  • You should use the above snippet in the web.config of your application.

Can the rule be configured?

You can overwrite the defaults by specifying custom values for the Content-Type header and the regular expressions that match the URLs for which those values should be required.

<regex>: <content_type_value>

E.g. The following rule configuration will make sonarwhal require that all resources requested from a URL that matches the regular expression .*\.js be served with a Content-Type header with the value of application/javascript; charset=utf-8.

In the .sonarwhalrc file:

{
"connector": {...},
"formatters": [...],
"rules": {
"content-type": ["error", {
".*\\.js": "application/javascript; charset=utf-8"
}],
...
},
...
}

Note: You can also use the ignoredUrls property from the .sonarwhalrc file to exclude domains you don’t control (e.g.: CDNs) from these checks.

How to use this rule?

To use it you will have to install it via npm:

npm install @sonarwhal/rule-content-type

Note: You can make npm install it as a devDependency using the --save-dev parameter, or to install it globally, you can use the -g parameter. For other options see npm's documentation.

And then activate it via the .sonarwhalrc configuration file:

{
"connector": {...},
"formatters": [...],
"parsers": [...],
"rules": {
"content-type": "error"
},
...
}

Further Reading