Debugging Chrome’s CSP Error: Why “frame-src *” Rejects Empty URL Frame Attempts


2 views

While working with Content Security Policy (CSP) implementations, I recently encountered a puzzling Chrome-specific behavior where attempting to frame an empty URL ('') triggers a CSP violation despite having frame-src * set. Here's my investigation and solution approach:

// Received error in Chrome console:
Refused to frame '' because it violates the following Content Security Policy directive: "frame-src *".

The error surfaces when trying to launch the client's default mail application through a mailto: link. Chrome interprets this as an attempt to frame a blank URL (essentially about:blank), which gets caught by CSP enforcement.

Current CSP header configuration:

default-src 'self';
script-src 'self' 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
frame-src 'self' *;
object-src 'none';
font-src 'self' data:;

Chrome's CSP implementation treats blank URLs specially:

  • The asterisk (*) doesn't actually cover about: schemes or empty URLs
  • This is a security measure to prevent potential injection attacks
  • Firefox and IE handle this case more leniently

Option 1: Explicitly allow blank URLs

frame-src 'self' * data: about:;

Option 2: Modify the mailto link behavior

// Instead of direct mailto link
document.getElementById('email-link').addEventListener('click', function(e) {
  e.preventDefault();
  window.location.href = this.href;
});

Option 3: Server-side CSP adjustment

# Apache configuration example
Header set Content-Security-Policy "default-src 'self'; ... frame-src 'self' * data: about:; ..."

While adding about: or data: to your CSP solves the immediate problem:

  • Be aware this slightly expands your attack surface
  • Monitor for any unexpected iframe behavior after implementation
  • Consider whether you truly need frame capabilities for your use case

Verify your changes using Chrome's CSP evaluator:

// Test URL pattern in CSP
new URL('about:blank').protocol === 'about:'; // true

Remember that CSP violations can also appear in different forms when dealing with browser extensions or built-in browser features.


Recently while working on a web application, I encountered a puzzling Content Security Policy (CSP) error in Chrome:

Refused to frame '' because it violates the following Content Security Policy directive: "frame-src *".

What makes this particularly confusing is that:

  • The error only occurs in Chrome (works fine in Firefox/IE)
  • We have frame-src * set in our CSP, which should allow all frames
  • The blocked content appears as an empty string ('')

The error occurs when users click a mailto link to open their default email client. Chrome seems to interpret this as a framing attempt, triggering the CSP violation.

Our current CSP configuration:

default-src 'self';
script-src 'self' 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
frame-src 'self' *;
object-src 'none';
font-src 'self' data:;

After extensive testing, I discovered Chrome handles mailto links differently than other browsers when CSP is involved:

  1. Chrome treats mailto link activation as a potential framing attempt
  2. Even with frame-src *, Chrome enforces additional security checks
  3. The empty string in the error suggests Chrome can't properly classify the mailto protocol

Here are three approaches that resolved this issue:

Solution 1: Add mailto to CSP

frame-src 'self' * mailto:;

This explicitly allows mailto links in frames (though technically they aren't frames).

Solution 2: Use a click handler

document.getElementById('mail-link').addEventListener('click', function(e) {
  window.location.href = 'mailto:user@example.com';
  e.preventDefault();
});

Solution 3: Meta tag workaround

For temporary fixes, you can set CSP via meta tag while testing:

<meta http-equiv="Content-Security-Policy" content="frame-src * mailto:">

After testing all solutions, I recommend:

# Apache configuration
Header set Content-Security-Policy "default-src 'self'; frame-src * mailto:; script-src 'self'; style-src 'self' 'unsafe-inline';"

This provides the broadest compatibility while maintaining security.