npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@hint/hint-no-html-only-headers

v3.0.23

Published

hint that that checks if HTML document only response headers are sent for other resources

Downloads

76,387

Readme

Unneeded HTTP headers (no-html-only-headers)

no-html-only-headers warns against responding with HTTP headers that are not needed for non-HTML (or non-XML) resources.

Why is this important?

Some HTTP headers do not make sense to be sent for non-HTML resources, as sending them does not provide any value to users and contributes to header bloat.

What does the hint check?

The hint checks if non-HTML responses include any of the following HTTP headers:

  • Content-Security-Policy
  • X-Content-Security-Policy
  • X-UA-Compatible
  • X-WebKit-CSP
  • X-XSS-Protection

In case of a JavaScript file, Content-Security-Policy and X-Content-Security-Policy will be ignored since CSP is also relevant to workers.

Examples that trigger the hint

Response for /test.js:

HTTP/... 200 OK

Content-Type: text/javascript; charset=utf-8
...
X-UA-Compatible: IE=Edge,
X-WebKit-CSP: default-src 'none'
X-XSS-Protection: 1; mode=block
...

Response for /test.html:

HTTP/... 200 OK

Content-Type: x/y
...
Content-Security-Policy: default-src 'none'
X-Content-Security-Policy: default-src 'none'
X-UA-Compatible: IE=Edge,
X-WebKit-CSP: default-src 'none'
X-XSS-Protection: 1; mode=block
...

Examples that pass the hint

Response for /test.js:

HTTP/... 200 OK

Content-Type: text/javascript; charset=utf-8
Content-Security-Policy: default-src 'none'
X-Content-Security-Policy: default-src 'none'
...

Response for /test.html:

HTTP/... 200 OK

Content-Type: text/html
...
Content-Security-Policy: default-src 'none'
X-Content-Security-Policy: default-src 'none'
X-UA-Compatible: IE=Edge,
X-WebKit-CSP: default-src 'none'
X-XSS-Protection: 1; mode=block
...

Response for /test.xml:

HTTP/... 200 OK

Content-Type: application/xhtml+xml
...
Content-Security-Policy: default-src 'none'
X-Content-Security-Policy: default-src 'none'
X-UA-Compatible: IE=Edge,
X-WebKit-CSP: default-src 'none'
X-XSS-Protection: 1; mode=block
...

How to configure the server to pass this hint

Apache can be configured to remove headers using the Header directive.

To remove the headers that are not needed for non-HTML resources, you can do something such as the following:

<IfModule mod_headers.c>

    # Because `mod_headers` cannot match based on the content-type,
    # the following workaround needs to be used.

    <FilesMatch "\.(appcache|atom|bbaw|bmp|crx|css|cur|eot|f4[abpv]|flv|geojson|gif|htc|ic[os]|jpe?g|m?js|json(ld)?|m4[av]|manifest|map|markdown|md|mp4|oex|og[agv]|opus|otf|pdf|png|rdf|rss|safariextz|svgz?|swf|topojson|tt[cf]|txt|vcard|vcf|vtt|webapp|web[mp]|webmanifest|woff2?|xloc|xpi)$">
        Header unset X-UA-Compatible
        Header unset X-XSS-Protection
    </FilesMatch>

    <FilesMatch "\.(appcache|atom|bbaw|bmp|crx|css|cur|eot|f4[abpv]|flv|geojson|gif|htc|ic[os]|jpe?g|json(ld)?|m4[av]|manifest|map|markdown|md|mp4|oex|og[agv]|opus|otf|png|rdf|rss|safariextz|swf|topojson|tt[cf]|txt|vcard|vcf|vtt|webapp|web[mp]|webmanifest|woff2?|xloc|xpi)$">
        Header unset Content-Security-Policy
        Header unset X-Content-Security-Policy
        Header unset X-WebKit-CSP
    </FilesMatch>
</IfModule>

Note that:

  • The above snippet works with Apache v2.2.0+, but you need to have mod_headers enabled 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.

For the complete set of configurations, not just for this rule, see the Apache server configuration related documentation.

If your application is adding the headers unconditionally to all responses and you cannot modify it, the solution is to create URL rewrite rules that will remove them from any resource whose Content-Type header isn't text/html:

<configuration>
     <system.webServer>
        <rewrite>
            <outboundRules>
                 <rule name="Content-Security-Policy">
                    <match serverVariable="RESPONSE_Content_Security_Policy" pattern=".*" />
                    <conditions>
                        <add input="{RESPONSE_CONTENT_TYPE}" pattern="^(text/html|text/xml|application/xhtml+xml|text/javascript|application/pdf|image/svg+xml)" negate="true" />
                    </conditions>
                    <action type="Rewrite" value=""/>
                </rule>
                <rule name="X-Content-Security-Policy">
                    <match serverVariable="RESPONSE_X_Content_Security_Policy" pattern=".*" />
                    <conditions>
                        <add input="{RESPONSE_CONTENT_TYPE}" pattern="^(text/html|text/xml|application/xhtml+xml|text/javascript|application/pdf|image/svg+xml)" negate="true" />
                    </conditions>
                    <action type="Rewrite" value=""/>
                </rule>
                <rule name="X-UA-Compatible">
                    <match serverVariable="RESPONSE_X_UA_Compatible" pattern=".*" />
                    <conditions>
                        <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" negate="true" />
                    </conditions>
                    <action type="Rewrite" value=""/>
                </rule>
                <rule name="X-WebKit-CSP">
                    <match serverVariable="RESPONSE_X_Webkit_csp" pattern=".*" />
                    <conditions>
                        <add input="{RESPONSE_CONTENT_TYPE}" pattern="^(text/html|text/xml|application/xhtml+xml|text/javascript|application/pdf|image/svg+xml)" negate="true" />
                    </conditions>
                    <action type="Rewrite" value=""/>
                </rule>
                <rule name="X-XSS-Protection">
                    <match serverVariable="RESPONSE_X_XSS_Protection" pattern=".*" />
                    <conditions>
                        <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" negate="true" />
                    </conditions>
                    <action type="Rewrite" value=""/>
                </rule>
            </outboundRules>
        </rewrite>
    </system.webServer>
</configuration>

Note that:

  • If your site uses a mime type different than text/html to serve HTML content (e.g.: application/xhtml+xml), you'll have to update the value of pattern.
  • The above snippet works with IIS 7+.
  • You should use the above snippet in the web.config of your application.

For the complete set of configurations, not just for this rule, see the IIS server configuration related documentation.

Can the hint be configured?

Yes, you can use:

  • include to specify additional HTTP headers that should be disallowed for non-HTML resources
  • ignore to specify which of the disallowed HTTP headers should be ignored

E.g. The following hint configuration used in the .hintrc file will make the hint allow non-HTML resources to be served with the Content-Security-Policy HTTP header, but not with Custom-Header.

{
    "connector": {...},
    "formatters": [...],
    "hints": {
        "no-html-only-headers": [ "warning", {
            "ignore": ["Content-Security-Policy"],
            "include": ["Custom-Header"]
        }],
        ...
    },
    ...
}

How to use this hint?

This package is installed automatically by webhint:

npm install hint --save-dev

To use it, activate it via the .hintrc configuration file:

{
    "connector": {...},
    "formatters": [...],
    "hints": {
        "no-html-only-headers": "error",
        ...
    },
    "parsers": [...],
    ...
}

Note: The recommended way of running webhint is as a devDependency of your project.