troccoli's avatar

Cannot close Flux Toast when CSP is enabled.

I have a Laravel app which uses Flux, and I cannot close the Toast by clicking on the X button, when I have CSP enabled.

I have the following CSP header (I have added newlines for readability)

base-uri 'self';
connect-src 'self' *.googletagmanager.com *.googleadservices.com *.google-analytics.com *.analytics.google.com *.g.doubleclick.net *.google.com pagead2.googlesyndication.com;
default-src 'self';
font-src 'self' fonts.gstatic.com fonts.bunny.net;form-action 'self';
frame-src 'self' *.googletagmanager.com *.googleadservices.com td.doubleclick.net;
img-src 'self' *.googletagmanager.com *.googleadservices.com *.google-analytics.com *.analytics.google.com *.g.doubleclick.net *.google.com pagead2.googlesyndication.com;
media-src 'self';
object-src 'none';
script-src 'self' 'nonce-BHEGmdju4S7Ht635wxYdsWZjbJtIUyz0' *.googletagmanager.com *.googleadservices.com *.google-analytics.com *.analytics.google.com *.g.doubleclick.net *.google.com pagead2.googlesyndication.com 'unsafe-eval';
style-src 'self' 'nonce-BHEGmdju4S7Ht635wxYdsWZjbJtIUyz0' fonts.googleapis.com fonts.bunny.net;
frame-ancestors 'none'

When the page loads I get the following in the browser's console

Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' 'nonce-VdwMkxDkhYrue0lqmeMKc2Da15AqUhA3' fonts.googleapis.com fonts.bunny.net". Either the 'unsafe-inline' keyword, a hash ('sha256-taOiJvFwCIELnoVAMuNfu+uAuWSkv20pPWS0piJHcO4='), or a nonce ('nonce-...') is required to enable inline execution. Note that hashes do not apply to event handlers, style attributes and javascript: navigations unless the 'unsafe-hashes' keyword is present.

Then, when I show the Toast and click on the X I get the following

Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src 'self' 'nonce-VdwMkxDkhYrue0lqmeMKc2Da15AqUhA3' *.googletagmanager.com *.googleadservices.com *.google-analytics.com *.analytics.google.com *.g.doubleclick.net *.google.com pagead2.googlesyndication.com 'unsafe-eval'". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution. Note that hashes do not apply to event handlers, style attributes and javascript: navigations unless the 'unsafe-hashes' keyword is present.

Adding unsafe-inline does not work because 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list.

Does anyone has any suggestions on how I can fix this?

0 likes
2 replies
LaryAI's avatar
Level 58

The issue is caused by CSP blocking inline event handlers (like onclick="") and inline styles (like style="") unless you explicitly allow them. Since you are using nonces for script-src and style-src, 'unsafe-inline' is ignored, and hashes do not apply to event handlers or style attributes unless you use 'unsafe-hashes'.

Why the Flux Toast can't be closed:
Flux (or your Toast implementation) likely uses inline event handlers (e.g., <button onclick="closeToast()">X</button>) or sets inline styles (e.g., element.style.display = 'none'). With your current CSP, these are blocked.

Solution

1. Avoid Inline Event Handlers

Change your Toast component to use event listeners in JavaScript, not inline HTML attributes.

Bad (blocked by CSP):

<button onclick="closeToast()">X</button>

Good (allowed by CSP):

<button id="toast-close">X</button>
<script nonce="BHEGmdju4S7Ht635wxYdsWZjbJtIUyz0">
    document.getElementById('toast-close').addEventListener('click', function() {
        // Close the toast
    });
</script>

Make sure the <script> tag has the correct nonce, matching your CSP.

2. Avoid Inline Styles

Do not use style="..." attributes. Instead, use CSS classes and toggle them via JavaScript.

Bad (blocked by CSP):

<div id="toast" style="display: none;">...</div>

Good (allowed by CSP):

<style nonce="BHEGmdju4S7Ht635wxYdsWZjbJtIUyz0">
    .hidden { display: none; }
</style>
<div id="toast" class="hidden">...</div>
<script nonce="BHEGmdju4S7Ht635wxYdsWZjbJtIUyz0">
    // To show the toast
    document.getElementById('toast').classList.remove('hidden');
    // To hide the toast
    document.getElementById('toast').classList.add('hidden');
</script>

3. If Using a JS Framework

If you are using a framework (like Vue, React, Alpine, etc.), make sure your build output does not use inline event handlers or inline styles. Most modern frameworks do not, but double-check.

4. If You Can't Change the Library

If Flux or your Toast library is injecting inline event handlers or styles, you have a few options:

  • Patch or fork the library to use event listeners and CSS classes.
  • Switch to a CSP-compatible toast library.
  • As a last resort, you can add 'unsafe-hashes' to your CSP and specify the hashes of the inline event handlers/styles, but this is cumbersome and not recommended for dynamic content.

5. Example CSP Update (if using hashes)

If you absolutely must allow a specific inline handler, you can add 'unsafe-hashes' and the correct hash to your script-src:

script-src 'self' 'nonce-BHEGmdju4S7Ht635wxYdsWZjbJtIUyz0' 'unsafe-hashes' 'sha256-...';

But again, this is not recommended for dynamic content.


Summary

  • Refactor your Toast code to avoid inline event handlers and styles.
  • Use external scripts with nonces and CSS classes for show/hide logic.
  • Make sure your CSP nonces match those in your HTML.
  • If using a third-party library that can't be changed, consider alternatives.

If you share your Toast component code, I can help you refactor it for CSP compliance.

troccoli's avatar
troccoli
OP
Best Answer
Level 6

I raised this issue with the FluxUI maintainers, issue 1748, so check that for a workaround (until they fix it)

Please or to participate in this conversation.