最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to let script to use setAttribute 'style' without breaking CSP - Stack Overflow

programmeradmin2浏览0评论

Im am trying to keep my CSP policy as strict as possible. I need to include 3d party component in my bundle. But it uses element.setAttribute('style'...) method which breaks CSP. Is there a way to allow this particular script to inline styles in that manner?

Im am trying to keep my CSP policy as strict as possible. I need to include 3d party component in my bundle. But it uses element.setAttribute('style'...) method which breaks CSP. Is there a way to allow this particular script to inline styles in that manner?

Share Improve this question edited Aug 23, 2019 at 22:26 Lee Kowalkowski 11.8k3 gold badges42 silver badges49 bronze badges asked Jun 17, 2017 at 20:05 maxvektormaxvektor 1471 silver badge7 bronze badges 4
  • 1 You could sanitize it yourself, use regex checking for script elements and so forth – Trash Can Commented Jun 17, 2017 at 20:08
  • I can solve it in this way, but I am afraid to freeze a 3d party component. There is no way to update it in the future. I still hope there is a possibility to fix it with 'nonce' attribute or something like that. – maxvektor Commented Jun 17, 2017 at 20:15
  • 1 Google reCAPTCHA is one common source that does this. See related answer at stackoverflow.com/questions/44512798/… – sideshowbarker Commented Jun 17, 2017 at 21:07
  • 1 Many 3rd party libraries don't set styles right, and I have had to 'fix' many of them for our own use because the original authors couldnt be bothered to do it themselves (even when asked). Annoying yes, but unless you can find a better alternative 3rd party library, editing it to work with your CSP is needed. – IncredibleHat Commented Jun 11, 2020 at 13:13
Add a comment  | 

4 Answers 4

Reset to default 7

Yes, there is a way.

There is much discussion about this here: https://github.com/w3c/webappsec-csp/issues/212

Which is succinctly summarised towards the end:

CSP is checked at parsing and blocks parsing the style attribute. Any direct operations go through.

Using setAttribute invokes the HTML parser and CSP is triggered.

So, instead of:

.setAttribute("style","background:red"); // needs HTML parsing

You would need:

.style.background = "red"; // direct manipulation

It may sound odd that one method works and the other does not, I think the understanding here is that there is a subtle difference between HTML attributes and DOM properties. https://joji.me/en-us/blog/html-attribute-vs-dom-property/

2018-10-06 update

The original answer here is still correct for now — because with CSP as currently implemented in browsers at least, there’s still no way to have dynamically injected styles at all without specifying unsafe-inline, and specifying unsafe-inline basically negates the whole purpose of CSP.

However, CSP3 adds a new unsafe-hashes expression for enabling you to allow particular inline scripts/styles. See https://w3c.github.io/webappsec-csp/#unsafe-hashes-usage, and see Explainer: ‘unsafe-hashes’, ‘unsafe-inline-attributes’ and CSP directive versioning. It hasn’t shipped in any browsers yet, though. So for the time being, the answer below still fully applies.


The only way to allow style attributes is to use unsafe-inline. It doesn’t matter whether the style attributes are coming from a different origin or from self—they’re still going to be considered a CSP violation unless you have unsafe-inline.

Specifically, one solution that won’t work for style attributes is to use a nonce or hash—because in CSP, nonce and hash usage are only defined for style and script elements; the spec has a Hash usage for style elements section that explicitly omits defining hash use for style attributes.

So even if in your policy you specify the correct hash for the contents of a style attribute, your browser will still handle it as a violation.

The bottom line is that since unsafe-inline is the only way to allow style attributes—but using unsafe-inline pretty much completely defeats the purpose of having any CSP policy to begin with—the only safe solution from a CSP perspective is just to never use style attributes—neither directly from your own markup/code nor by way of any third-party code.

For anyone looking for a jQuery patch to change setting the style attrib into setting the proper css values, here is one I use (sourced from this Github but with an important bug fix to make it work correctly):

var native = jQuery.attr;
jQuery.attr = function (element, attr, value) {
    if (attr === 'style') {
        resetStyles(element);
        return applyStyles(element, value);
    } else {
        //native.apply(jQuery, arguments);
        return native(element, attr, value);
    }
};

function applyStyles(element, styleString) {
    if (styleString) {
        var styles = styleString.split(';');
        styles.forEach(function (styleBit) {
            var parts = styleBit.split(':');
            var property, value;
            if (parts.length === 2) {
                property = parts[0].trim();
                value = parts[1].trim();

                element.style[property] = value;
            }
        });
        return styleString;
    }
}

function resetStyles(element) {
    var styleList = [].slice.call(element);
    styleList.forEach(function (propertyName) {
        element.style.removeProperty(propertyName);
    });
}

It is strange why the '3 years old' question appeared in the new ones, and why the topicstarter's issue still unsolved.

The issue of using element.setAttribute('style', ...) without causing a CSP violation is easily solved with a little hack that globally replaces the problematic element.setAttribute('style') with the safe element.style.ptop = '...'. After that you can use setAttribute('style') without breaking CSP, this will fix jQuery and other libs too.

Solutions using only the CSP itself will be ineffective because:

  • the 'unsafe-hashes' token is still not supported in all browsers.
  • in the case of third-party JavaScript libraries that actively use dynamic styles through 'setAttribute('style')', it is technically impossible to maintain a list of dozens of hashes. In addition, CSP headers are limited in size.

cakeboeing727 started on the right track, but unfortunately the idea of the new contributor was not heard by society. It's a pity.

发布评论

评论列表(0)

  1. 暂无评论