All 30 checks Missing X-Content-Type-Options nosniff
Missing X-Content-Type-Options nosniff
Updated
Without X-Content-Type-Options: nosniff, a browser may look at the contents of a file and decide it is a different type from the one your server declared, which attackers can abuse to get a harmless-looking upload run as a script.
HTTP/2 200
content-type: text/html; charset=utf-8
cache-control: public, max-age=0X-Content-Type-Options: nosniffThe fix for your stack
Fix for: Next.js / Vercel
// next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
async headers() {
return [
{
source: "/:path*",
headers: [{ key: "X-Content-Type-Options", value: "nosniff" }],
},
];
},
};
export default nextConfig;What content sniffing is
Servers label each file with a content type, such as text/plain or image/png. Old browsers were forgiving: if the label looked wrong, they inspected the first bytes of the file and guessed. That helped with misconfigured servers, but it created an attack. If a site lets users upload files, an attacker can upload a text file that contains script, and a browser that sniffs it as HTML or JavaScript may run it in your site's context.
The nosniff value turns that guessing off. The browser trusts the declared type, and for scripts and styles it refuses to run a file whose type does not match. It costs nothing, has almost no downside on a correctly configured site, and is part of the baseline set of security headers that scanners list. If a file suddenly stops loading after you add it, the cause is a wrong content type on that file, which is worth fixing.
How Skewcheck detects it
Skewcheck reads the response headers of the page. If x-content-type-options is present and its value is nosniff, compared without regard to capitalisation, the check passes. If the header is missing, or is set to anything else, the check fails with medium severity and removes 3 points from the score.
Only the page's own response is checked. Skewcheck does not request your images, scripts or downloads to see whether they carry the header, so set it for all paths. Header names are case-insensitive, so the lowercase form shown by HTTP/2 is the same header.
curl -sI https://example.com | grep -i x-content-type-optionsAdding it on your platform
The fix is one line, applied to every response. The tabs above show it for nginx, Apache, Netlify, Cloudflare, Next.js, Webflow, Framer and WordPress. In nginx, use the always flag so the header also appears on error pages. In Next.js, return it from the headers function in the config file. For platforms that let you add custom response headers only on some plans, the snippet shows the route and mentions a Cloudflare proxy as an alternative when the plan does not allow it.
Some hosts already send the header by default, so check the live response before adding a duplicate. After deploying, request a few paths, not just the home page, to confirm that static files and error pages also carry it, then re-run the check.
Before and after
HTTP/2 200
content-type: text/html; charset=utf-8HTTP/2 200
content-type: text/html; charset=utf-8
x-content-type-options: nosniffCheck your page
Run all 30 checks on any URL. Free, no account.