Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Content security policy syntax for base64 data uris

I'm trying to programatically alter a pdf preview page inside a chrome extension that extends devtools.

manifest

  "content_security_policy": "img-src 'self' data; script-src 'self'; object-src 'self'; data-uri 'self'"

When I set the src attribute to an iframe I can successfully load the pdf and it will be generated dynamically.

<iframe src="data:application/pdf;base64,..."></iframe>

However, when I try the same for an embed or object html element I get:

<embed src="data:application/pdf;base64,...">
<object data="data:application/pdf;base64,..."></object>

Refused to load plugin data from 'data:application/pdf;base64,{{data}}' because it violates the following Content Security Policy directive: "object-src 'self'".

Why? Resetting the src attribute on an iframe is giving focus to the nested content window, so when the user is typing in the parent window suddenly the textarea is blurred (it's really annoying). I thought that using an embed or object element would mitigate the nested document problem.

What is the correct csp syntax in order to get embeds working correctly? I'm looking directly at the w3 docs it's not really helping. For instance, I tried the following syntax in my manifest:

"content_security_policy": "object-src 'self' data"

...which will throw an error when you try to refresh the extension in chrome://extensions.

like image 713
Daniel Lizik Avatar asked Jan 28 '26 05:01

Daniel Lizik


1 Answers

The reason that it works for <iframe> is that that the extension's default Content security policy does not block any frames. It only restricts scripts and plugins.

The relevant part of the CSP for plugins is:

object-src 'self' blob: filesystem:

On normal web pages, you would use "content_security_policy": "object-src 'self' blob: filesystem: data:" to allow data:-URLs to be embedded. This is not allowed in extensions, so you cannot load data:-URLs in plugins. If you try to add this "data:" directive anyway, then it will be ignored. When developer mode and "Collect errors" is enabled at chrome://extensions, the error log (not the JS console) will display:

Ignored insecure CSP value "data:" in directive 'object-src'.

To load a PDF in an extension via <embed> or <object>, try one of the whitelisted schemes:

var pdfBlob = new Blob(['%PDF raw pdf data here...'], {
    type:'application/pdf'
});
var pdfUrl = URL.createObjectURL(pdfBlob);

var embed = document.createElement('embed');
embed.src = pdfUrl;
embed.type = 'application/pdf';  // Optional
document.body.appendChild(embed);
like image 157
Rob W Avatar answered Jan 30 '26 20:01

Rob W