Jquery +datatables causing CSP errors for inline style

Tags: , , ,



I have been trying to get rid of the unsafe-inline from the CSP style-src headers as it is vulnerable. While removing this, I am getting below errors in jQuery execution in chrome:

Refused to apply inline style because it violates the following Content Security Policy directive: “style-src ‘self’ ‘nonce-TXYxR0tlamZ1emk2a3Y4RHFwdTdTZ0JaR1R2TTdEaUk=’ ‘unsafe-eval’ “. Either the ‘unsafe-inline’ keyword, a hash (‘sha256-Z0MkpGRk0/9QW+7eJ/G1D//1i6WKVbat+HlIwkiFln4=’), or a nonce (‘nonce-…’) is required to enable inline execution

While debugging I found that it is failing at

From jquery 3.5.1

    tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; 

in buildFragment method. At failing point ,elem is evaluated as a string which contains the html for tr containing inline style generated by the datatables.Even though the datatables seems to be applying CSP safe way as below but when it gets passed back to jQuery whole TR containing inline style is loaded as innerHTML which gets failed due to unsafe-inline

from datatables.js 1.10.21

_fnApplyToChildren( function(nSizer, i) {
            nSizer.innerHTML = '<div class="dataTables_sizing">'+footerContent[i]+'</div>';
            nSizer.childNodes[0].style.height = "0";
            nSizer.childNodes[0].style.overflow = "hidden";
            nSizer.style.width = footerWidths[i];
        }, footerSrcEls );
    }

As seen above datatables is applying inline styles in CSP acceptable way as they are applying style property directly on the elements style property Below is the run time value that gets evaluated in “elem” in jquery buildFragment method containing inline styles

<tr role="row"><th class="dataGridCheckBoxCell sorting" aria-controls="tablegrid" rowspan="1" colspan="1" aria-label=": activate to sort column ascending" style="padding-top: 0px; padding-bottom: 0px; border-top-width: 0px; border-bottom-width: 0px; height: 0px; width: 41px;" role="columnheader"><div class="dataTables_sizing" **style="height: 0px; overflow: hidden;"**><div id="checkAllQueues" class="selectable" role="checkbox"></div>

I am not sure if it is a data tables issue or jquery or combination of both. Any insight on the issue will be helpful or any workaround that can be applied

Answer

Yeah, it’s specifics of jQuery buildFragment DataTables plugin creates “fragments” in a CSP safe way, but after that the buildFragment keeps those as HTML string and inserts it as HTML.

jQuery has htmlPrefilter() method to modify all existing jQuery manipulation methods. buildFragment uses this method when it wraps stored elements:
tmp.innerHTML = '<div>' + htmlPrefilter(elem) + '</div>';

You can to modify this htmlPrefilter() to make style='...' -> data-style='...' within all tags. On document is ready event yo need to select all data-style attributes, to parse its content into array and aplly CSP safe element.style= to each array’s elements.



Source: stackoverflow