简体   繁体   中英

Content Security Policy with Dynamic Button

I'm implementing Content Security Policy (CSP) on a site. Below is the CSP policy that I'm testing.

Content-Security-Policy: script-src 'self' 'nonce-random' 'strict-dynamic';

The site uses a third party js script library. The script library injects dynamic content on a page. The dynamic content has inline event handlers. Below is a simple HTML page with a script that mimics the site + the third party library's behavior.

<!DOCTYPE html>
<html>
<head>
    <title>CSP Test Page</title>
    <script nonce="random">
        document.addEventListener('DOMContentLoaded', function (event) {
            var el = document.createElement('button');
            el.innerHTML = 'Click Me';
            el.setAttribute('onclick', "doSomething()");
            document.body.appendChild(el);
        });

        function doSomething() {
            alert('I did something.');
        }
    </script>
</head>
<body>
</body>
</html>

The inline event handlers on the dynamically added button triggers the following error message in the Chrome console:

Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src 'self' 'nonce-random' 'strict-dynamic'". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.

Any suggestions on how to address this issue from a CSP standpoint? I can't change the code of the third party library that is adding the dynamically generated content with the inline event handler.

CSP blocks all inline event handlers, including code added by the third-party library, so unfortunately there is no simple way to solve this without refactoring the CSP-incompatible dependency.

In the long term, CSP3 might provide the ability to whitelist trusted scripts inside event handlers via the 'unsafe-hashed-attributes' feature, but this isn't yet shipping in any stable browser.

In the meantime, one possible workaround is manually removing the attribute with the inline event handler after invoking the external library. That is, you could do something like:

var el = document.createElement('button');
library.doStuff(el);

// Now that the library has run we will change the DOM to be compatible with CSP.
el.onclick = function() { doSomething() };
el.removeAttribute('onclick');

Note that assigning a function to the onclick property directly is okay when it comes to CSP, as opposed to setting the onclick attribute on the HTML element, which is blocked by CSP because it converts a string to code. This will work and avoid CSP violations, but it only makes sense if there is a small number of instances of inline event handlers in the library; otherwise this could get quite tedious.

As a side note, your CSP might benefit from fallbacks for older browsers which don't support 'strict-dynamic' , similar to this example .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM