CSP

upgrade-insecure-requests — What It Does and When to Use It

Updated April 2026

Reading this? Verify your fix live. Scan your CSP → CSPFixer

upgrade-insecure-requests is a CSP directive that automatically upgrades HTTP resource requests to HTTPS before the browser makes them. It is a fast fix for mixed content warnings — but only works if the resources actually exist on HTTPS.

How it works

# Without upgrade-insecure-requests:
# <img src="http://cdn.example.com/image.jpg">
# Browser requests: http://cdn.example.com/image.jpg
# → Mixed content warning

# With upgrade-insecure-requests:
# Browser upgrades to: https://cdn.example.com/image.jpg before making the request
# → No mixed content warning (if https resource exists)

Add to your CSP

# As a standalone directive (no value needed)
Content-Security-Policy: upgrade-insecure-requests; default-src 'self';

# With other directives
Content-Security-Policy: upgrade-insecure-requests; default-src 'self'; script-src 'self'; img-src 'self' https:;

Config by stack

Nginx

add_header Content-Security-Policy "upgrade-insecure-requests; default-src 'self';" always;

Vercel (vercel.json)

{ "headers": [{ "source": "/(.*)", "headers": [{ "key": "Content-Security-Policy", "value": "upgrade-insecure-requests; default-src 'self';" }] }]
}

What it upgrades — and what it does not

Resource typeUpgraded?Notes
Images (<img src="http://...">)✅ YesPassive mixed content — upgraded
Scripts (<script src="http://...">)✅ YesActive mixed content — upgraded
Stylesheets✅ YesUpgraded
The page URL itself❌ NoUse HSTS for this
Form action URLs✅ YesUpgraded
XHR/fetch URLs in JavaScript❌ NoMust fix in code

upgrade-insecure-requests vs block-all-mixed-content

# upgrade-insecure-requests → attempts HTTPS, fails gracefully if not available
Content-Security-Policy: upgrade-insecure-requests;

# block-all-mixed-content → blocks HTTP resources entirely, no upgrade attempt
Content-Security-Policy: block-all-mixed-content;

# Use upgrade-insecure-requests first — less disruptive
# Only switch to block-all-mixed-content once all resources are on HTTPS

The complete mixed content fix

# Three layers working together:
# 1. upgrade-insecure-requests — upgrades HTTP resource requests
Content-Security-Policy: upgrade-insecure-requests;

# 2. HSTS — forces HTTPS for the page itself
Strict-Transport-Security: max-age=31536000; includeSubDomains

# 3. Fix hardcoded HTTP URLs in your code — the real fix
# Find with: grep -r "http://" ./src --include="*.js" --include="*.html"
Scan your CSP → CSPFixer
Check if your domain is on the HSTS preload list → HSTS Preload Checker