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