jashkenas / underscore

JavaScript's utility _ belt
https://underscorejs.org
MIT License
27.29k stars 5.53k forks source link

underscore.js requires CSP to use 'unsafe-eval' #2995

Closed BowFarmer closed 4 months ago

BowFarmer commented 4 months ago

On line 936 there is a call to new Function:

render = new Function(argument, '_', source);

This requires use of 'unsafe-eval' when creating a Content Security Policy for scripts. Would it be possible to change this so 'new Function' is not used?

I don't find underscore.min.js being used on my frontend WordPress, but I do see it included on the admin side of my Wordpress. So when I create the CSP for the admin side, I need to check if the html includes underscore.min.js, and add 'unsafe-eval' to my script CSP.

jgonggrijp commented 4 months ago

That line is actually line 87 of the template module:

https://github.com/jashkenas/underscore/blob/1abc36c169947c54c97e266513b1d763d0198f46/modules/template.js#L87

and the trick here is that a template is compiled into JavaScript code. That code can only be executed if you pass it through Function first (or eval, but that would be worse from a security perspective). So no, it cannot be avoided.

I mean, the new is not really necessary here, but the Function is. And I think the Function part is what requires the unsafe-eval directive.

I will close this ticket now because there is nothing we can do, but please feel free to respond if you have any more questions or comments.

BowFarmer commented 4 months ago

Hi Julian,

Thank you for replying to my query. I guess there is nothing that can be done. Fortunately I do not see underscore.js being used on the frontend side of my WordPress site. Just on the admin side.

I dynamically generate a CSP and create hashes for all inline scripts. And on the admin side I also do this check to add ‘unsafe-eval’ when certain scripts are included:

if (false !== strpos($page_html, 'block-templates/index.js') || false !== strpos($page_html, 'underscore.min.js') || false !== strpos($page_html, 'handlebars.min.js')) { $extra_script_rules .= " 'unsafe-eval' "; }

This enables me from using ‘unsafe-eval’ in the CSP for any admin pages which do not use any of those scripts. Thankfully, I have not found any situation where I need ‘unsafe-eval’ in the CSP for the frontend side.