segmentio/analytics.js-core

Don't use new Function()

Closed this issue ยท 10 comments

The distributed version of analytics.js currently uses new Function(), which doesn't work with Content-Security-Policy headers unless you add 'unsafe-eval' to script-src. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Unsafe_eval_expressions

Moved from segmentio/analytics.js#578

Can you clarify where you are seeing this? I am not seeing this in this codebase.

I'll check it out!

This is due to a transitive dependency on this package https://github.com/ndhoule/arity, from https://github.com/ndhoule/arity/blob/master/index.js#L69.

+-- @segment/analytics.js-core@3.7.2
| +-- @ndhoule/after@1.0.0
| | `-- @ndhoule/arity@2.0.0

Here's a few possible options as I see it:

I'm also not that familiar with Content-Security-Policy headers - could you describe how this is sued and how it applies to analytics.js? I'm a bit surprised this is the first time we've heard about it from a customer...

Thanks for investigating!

I'm also not that familiar with Content-Security-Policy headers - could you describe how this is sued and how it applies to analytics.js?

I'm no expert myself, but I'll try ๐Ÿ™‚ Basically CSP helps reduce the risk of XSS. It specifies the sources a browser will allow connections to from that website. You can specify things like script-src, which is a whitelist of allowed sources and methods to load scripts from. https://content-security-policy.com/ might give a simpler overview.

For instance, after implementing CSP we've seen a few users break the security policy because of malware browser extensions injecting scripts from all kinds of bad sources into the page. Hopefully CSP helps protect them.

Anyway, CSP applies to all resources, so this of course includes analytics.js. If you don't add 'unsafe-eval' as an allowed script-src, the browser should refuse to execute the new Function call.

I'm a bit surprised this is the first time we've heard about it from a customer...

Me too ๐Ÿ™‚ I don't think it's too widely used yet, but surely it'll only become more common. Tools like Mozilla's Observatory already highlight unsafe or missing CSP headers, as do many other security scanners.

Got it. "after implementing CSP" -> could you clarify what it means to implement CSP? I'm wondering how we can replicate your setup and understand what this looks like.

Of course, sorry! It's just an HTTP header sent by the server: Content-Security-Policy: <insert policy>. For instance, Content-Security-Policy: default-src https:; script-src 'nonce-{random}'; object-src 'none' (from https://csp.withgoogle.com/docs/index.html)

Here's Google's guide: https://developers.google.com/web/fundamentals/security/csp/

Any new info on this? We have the same problem. We're adding a Content-Security-Policy header when serving our web app and to use analytics.js we have to add 'unsafe-eval' to our script-src directive.

The CSP issue is deeply rooted in the JS ecosystem and transitive dependencies. We have done our best effort to identify and fix this issue under core AJS code as well as replaced direct dependency on packages causing this. However, this issue is not fully resolved due to other dependencies. We look to completely resolve this issue in the coming months.

@danieljackins Is there another issue tracking your ongoing efforts to resolve this issue that I can track?