EPUB is an open standard that allows book authors to embed JavaScript inside the e-book itself. When a browser renders that content, the scripts run with the same privileges as your application — they can read cookies, make network requests, and access the DOM of the host page. foliate-js renders EPUB content inside iframes loaded fromDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/johnfactotum/foliate-js/llms.txt
Use this file to discover all available pages before exploring further.
blob: URLs, which share your page’s origin, so any script inside an untrusted book file has direct access to your application.
Why this is hard to solve at the library level
There are two reasons foliate-js cannot make scripted EPUB content safe on its own:-
Same-origin
blob:URLs. Book sections are loaded asblob:URLs. Browsers treatblob:URLs as same-origin with the page that created them, so an iframe sandbox that blocks scripts would also break the ability to load resources from within the book. There is currently no way to useblob:URLs and enforce cross-origin isolation at the same time. -
WebKit Bug 218086. The
allow-scriptsattribute is required on iframes when running under WebKit (including Safari and WebKitGTK). This makes iframe sandboxing useless as a defense against scripted content on those platforms.
What Content Security Policy does
CSP is an HTTP response header (or<meta> tag) that tells the browser which sources of executable content are allowed. By setting a policy that blocks all scripts except those from 'self', you prevent any <script> tag inside an e-book section from executing, regardless of how it was loaded.
This is the minimum policy you need:
'self') while blocking inline scripts and scripts from any other source — including those inside blob: URLs produced by foliate-js.
How to apply CSP
HTTP response header
The most reliable approach is to set the header on your server. The exact syntax depends on your server or hosting platform:Meta tag fallback
If you cannot set HTTP headers (for example, when serving from a CDN that does not support custom headers), you can place a<meta> tag in the <head> of your HTML page:
The
<meta> tag approach has limitations: it cannot restrict certain directives (such as frame-ancestors), and the policy only applies to resources loaded after the tag is parsed. Prefer the HTTP header approach when possible.