Skip to content
Pro Analyzer — Available with ShieldCI Pro

MIME Sniffing Protection Analyzer ​

Analyzer IDCategorySeverityTime To Fix
mime-sniffing🛡️ SecurityHigh5 minutes

What This Checks ​

This analyzer validates that your application sends the X-Content-Type-Options: nosniff header to prevent browsers from performing MIME type sniffing on responses. It makes a live HTTP request to a guest route (login page or homepage) to verify the header at the server level:

  • Missing header - Checks if the X-Content-Type-Options header is present in HTTP responses
  • Invalid value - Verifies the header value is nosniff (the only valid value per spec)
  • Duplicate headers - Detects multiple X-Content-Type-Options headers that can cause inconsistent browser behavior
  • Non-2xx response - Warns instead of checking the header when the guest route, after any same-host redirects, does not answer with a 2xx response

Why It Matters ​

MIME sniffing (content sniffing) occurs when browsers ignore the declared Content-Type header and try to guess the actual content type by examining the file's content. This can lead to:

  • XSS attacks - An attacker uploads an HTML file disguised as an image; the browser executes it as HTML with scripts
  • Content type confusion - Files served with one type get interpreted as another, bypassing security controls
  • User-uploaded content execution - PDFs, images, or documents containing embedded scripts get executed
  • Drive-by downloads - Browser vulnerabilities can be exploited through MIME type confusion

This is especially critical for applications that allow user file uploads or serve user-generated content.

How to Fix ​

Quick Fix (2 minutes) ​

Add the header via Laravel middleware:

php
// app/Http/Middleware/SecurityHeaders.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class SecurityHeaders
{
    public function handle(Request $request, Closure $next)
    {
        $response = $next($request);

        $response->headers->set('X-Content-Type-Options', 'nosniff');

        return $response;
    }
}

Register in your bootstrap/app.php or app/Http/Kernel.php:

php
// bootstrap/app.php (Laravel 11+)
->withMiddleware(function (Middleware $middleware) {
    $middleware->append(\App\Http\Middleware\SecurityHeaders::class);
})

Proper Fix (5 minutes) ​

Configure the header at the web server level for all responses:

Nginx:

nginx
server {
    # Add to all responses
    add_header X-Content-Type-Options "nosniff" always;
}

Apache (.htaccess):

apache
<IfModule mod_headers.c>
    Header always set X-Content-Type-Options "nosniff"
</IfModule>

Combined approach (recommended):

php
// Set at both web server AND application level for defense in depth
// app/Http/Middleware/SecurityHeaders.php
class SecurityHeaders
{
    public function handle(Request $request, Closure $next)
    {
        $response = $next($request);

        $response->headers->set('X-Content-Type-Options', 'nosniff');
        $response->headers->set('X-Frame-Options', 'SAMEORIGIN');
        $response->headers->set('X-XSS-Protection', '1; mode=block');

        return $response;
    }
}

ShieldCI Configuration ​

This analyzer is automatically skipped in CI environments ($runInCI = false) and only runs in production and staging.

Why skip in CI and development?

  • The check makes actual HTTP requests to verify response headers, which requires a live server
  • CI and local environments don't serve production-equivalent HTTP responses
  • MIME sniffing protection is a web server configuration concern, not a code-correctness concern

When to run this analyzer:

  • ✅ Production servers: Confirms MIME sniffing protection is active
  • ✅ Staging servers: Validates header configuration before production deploy
  • ❌ Local development: Skipped (localhost URLs not tested)
  • ❌ CI/CD pipelines: Skipped automatically

References ​