Repository navigation
Security warning: avoid using function constructor. #897
Copy link
Copy link
Closed
Labels
communitycommunity contributioncommunity contribution
Description
I recently discovered that one of plotly.js's dependency is using Function constructor.
Unfortunately, I can't tell exactly which one, but the code doesn't seems to belong to plotly itself.
Here is Chrome's error message:
plotly.js:74222Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is
not an allowed source of script in the following Content Security Policy directive: "script-src 'self'
www.google-analytics.com ajax.googleapis.com 'nonce-67df8dace6ea7feb57cab73e41ebe0c7'".
makeOp @ plotly.js:74222
(anonymous function) @ plotly.js:74244
455.cwise-compiler @ plotly.js:74271
s @ plotly.js:7
(anonymous function) @ plotly.js:7
129.ndarray @ plotly.js:25687
s @ plotly.js:7
(anonymous function) @ plotly.js:7
138../lib/shaders @ plotly.js:27330
s @ plotly.js:7
(anonymous function) @ plotly.js:7
798.../../constants/gl3d_dashes @ plotly.js:127609
s @ plotly.js:7
(anonymous function) @ plotly.js:7
800.../../constants/gl_markers @ plotly.js:128154
s @ plotly.js:7
(anonymous function) @ plotly.js:7
15.../src/traces/scatter3d @ plotly.js:355
s @ plotly.js:7
(anonymous function) @ plotly.js:7
12../bar @ plotly.js:312
s @ plotly.js:7
e @ plotly.js:7
(anonymous function) @ plotly.js:7
a @ plotly.js:7
(anonymous function) @ plotly.js:7
__webpack_require__ @ bootstrap 08e5224…:585
fn @ bootstrap 08e5224…:109
(anonymous function) @ svg-to-png.js:2
__webpack_require__ @ bootstrap 08e5224…:585
fn @ bootstrap 08e5224…:109
(anonymous function) @ commons.js:36658
__webpack_require__ @ bootstrap 08e5224…:585
fn @ bootstrap 08e5224…:109
(anonymous function) @ index.js:1
__webpack_require__ @ bootstrap 08e5224…:585
fn @ bootstrap 08e5224…:109
(anonymous function) @ bootstrap.js:9
__webpack_require__ @ bootstrap 08e5224…:585
fn @ bootstrap 08e5224…:109
(anonymous function) @ index.js:3
__webpack_require__ @ bootstrap 08e5224…:585
fn @ bootstrap 08e5224…:109
(anonymous function) @ index.js:8
__webpack_require__ @ bootstrap 08e5224…:585
webpackJsonpCallback @ bootstrap 08e5224…:21
(anonymous function) @ index.js:1
Function constructor is considered by browser's CSP as an equivalent of eval.
Therefore, we can't setup a good Content Security Policy, unless we allow 'unsafe-eval' which is a whole in the policy itself.
It is possible to identify the faulty dependency, and maybe provide a workaround ?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
communitycommunity contributioncommunity contribution
Activity
rreusser commentedon Sep 2, 2016
I think this is the line: https://github.com/scijs/cwise-compiler/blob/master/lib/compile.js#L351
cwise is a library that performs operations on ndarrays. It doesn't look like plotly uses the cwise browserify transform when bundling plotly.js, but I believe even the transformed version that does the parsing ahead of time still compiles an optimized version (i.e.
new Function) at runtime.Long story short, this is pretty central to what cwise does, so I'm not totally sure of a good workaround, unless there's a way to short-circuit the optimization and just perform naive operations on data.
Edit: more precisely, this looks like it might be coming from ndarray-ops, which is already transformed, but the problem remains the same. Looks like it's coming from here. That wouldn't be too hard to rewrite naively, but I'd be surprised if cwise didn't creep in somewhere else in the dependencies.
etpinard commentedon Sep 2, 2016
The plotly build step doesn't explicitly list the
cwisetransform, but several of our dependencies havecwiselisted in their respective package.json namelyndarray-fill,ndarray-wrapandgl-select-static(ref this script).willemx commentedon Apr 12, 2017
I'm also running into this problem. Can't run my (Meteor) app because of this.
Is there a work-around maybe?
jacobq commentedon Feb 27, 2018
When I tried to bring plotly.js into my Electron application (via ember-plotly-shim) it triggers a security warning. In fact, since I have a set a Content-Security-Policy per the recommendations, it does not run at all.
Would someone be willing to write some / point to some documentation that describes how to incorporate plotly w/o using a pipeline that evaluates strings as code?
fxfilmxf commentedon Mar 9, 2018
Still seeing this as well. Hasn't been addressed at all.
etpinard commentedon Mar 9, 2018
Nothing has changed since #897 (comment), so yes this hasn't been addressed at all 😱
The problematic
cwisetransform is only used in gl3d and gl2d (excludingscattergl), so using one of the partial bundles that don't include these trace types would solve this issue. Better yet, bundling plotly.js yourself may do the trick.fxfilmxf commentedon Mar 9, 2018
Thanks for the advice! I'll take a look at that.
jtal commentedon Nov 6, 2018
Does anyone have the CSP header they've used to keep security as tight as possible but still use plotly?
jacobq commentedon Nov 7, 2018
@jtal
I recommend starting with the strictest options and gradually relaxing restrictions until your application functions properly. There may be other parts of your work that won't work when fully restricted. As an example only, here is one I have used (inside of an electron app):
default-src 'none'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; connect-src 'self'; img-src 'self' 'data:'; style-src 'self' 'unsafe-inline'See MDN
anders-kiaer commentedon Feb 12, 2020
Looks like the direct
plotly.jsdependencies today that makeplotly.jsdependent oncwiseare:ndarray-fillndarray-homographygl-plot2dgl-plot3dDoes anyone know if it is feasible for
plotly.jsto go away from these dependencies (any alternatives?) and/or modify the dependencies themselves to not usecwise?The
unsafe-evalrequirement is unfortunately currently stopping us from being allowed to useplotly.js's variant of parallell coordinates, as it appears to be part of thegl2dbundle, which then looks to be indirectly requiringcwise, ref. #897 (comment).etpinard commentedon Feb 12, 2020
@anders-kiaer you may be interested in https://www.npmjs.com/package/plotly.js-gl2d-dist, you can install it using
which has no dependencies.
anders-kiaer commentedon Feb 12, 2020
Thanks @etpinard 🙂 Hmm, not sure if I understand, isn't the
cwisedependency bundled into thegl2ddist? I tried using the dist fromnpm install plotly.js-gl2d-dist, and also what I think is the CDN equivalent, and got the same CSP block without'unsafe-eval'. Tested using this Dash snippet:which when looking at the browser console gives a
unless
'unsafe-eval'is added. Searching throughplotly-gl2d.jsgives me 18 hits onFunction(. The first hit looks to come from this line.etpinard commentedon Feb 12, 2020
My mistake. I thought you were worried about the "unsafe-eval" behavior of
cwisewhen bundling your own custom bundle, not in the browser runtime.Unfortunately, there's no easy way for us to simply replace
cwise. This package can improve performance by a large amount.etpinard commentedon Feb 12, 2020
But, the
basic,cartesian,geo,mapboxandfinancepartial bundles should be fine.That is, bundles that include trace types other than
gl3d,gl2d,scatterglandsplomshould pass the "unsafe-eval" checks.11 remaining items
archmoj commentedon Aug 31, 2020
@polx could you please use the unminified version i.e. "plotly-latest.js" instead to re-produce the list?
polx commentedon Sep 2, 2020
Sorry @archmoj , it is called plotly-min but is a copy of plotly.js.
I just downloaded 1.54.7 again and compared and they are equal:
diff lib/plotly-latest.min.js /tmp/plotly.js-1.54.7/dist/plotly.jsis empty (and both have md5 8948b85ca08520fa7ff3718ffe40dd4e).paul
jackparmer commentedon Sep 10, 2020
This issue has been tagged with
NEEDS SPON$ORA community PR for this feature would certainly be welcome, but our experience is deeper features like this are difficult to complete without the Plotly maintainers leading the effort.
Sponsorship range: $45k-$50k
What Sponsorship includes:
Please include the link to this issue when contacting us to discuss.
nicolaskruchten commentedon Oct 6, 2020
Great news: Equinor is generously willing to sponsor $15k of this work if we can find sponsors for the rest! Please let us know if you're able to contribute part of the remaining $30k-$35k and we can get started on this project :)
archmoj commentedon Dec 14, 2020
Here is the complete list of function constructors and their dependency path from different bundles.
dependency: d3
at:
dependency: es6-promise
at:
and
at:
dependency: binary-search-bounds
at:
dependency: box-intersect
at:
dependency: cwise-compiler
at:
and
at:
dependency: gl-shader
at:
and
at:
and
at:
dependency: binary-search-bounds
at:
dependency: ndarray-extract-contour
at:
dependency: ndarray-ops
at:
dependency: ndarray
at:
and
at:
and
at:
dependency: robust-in-sphere
at:
dependency: robust-orientation
at:
dependency: surface-nets
at:
dependency: incremental-convex-hull
at:
dependency: ndarray-sort
at:
and
at:
and
at:
and
at:
and
at:
dependency: robust-determinant
at:
dependency: robust-linear-solve
at:
dependency: simplicial-complex-contour
at:
tdelmas commentedon Dec 21, 2020
@archmoj Here is the list of GitHub repository involved in the list you provided, with, when available, the issue and/or the PR about CSP:
As @mikolalysenko / @scijs doesn't seam to want to address the problem, most of the dependency you cited (probably around 50 packages?) may require to be forked...
nicolaskruchten commentedon Jan 5, 2021
It seems like a fair number of the items above that impact
gl2dstem fromgl-contour2d, so dropping support for thecontourgltrace would resolve a number of these for thegl2dbundle, right?nicolaskruchten commentedon Feb 18, 2021
An update: thanks to generous sponsorship from Equinor, we have been able to make substantial progress on this issue! I've just posted the pre-release announcement for Plotly.js 2.0, which will include the following changes related to this issue:
basic,cartesian,finance,geo, andmapbox.strictwill be supported from now on, and it contains the maximal subset of the library which is function-constructor-free (see link for list of trace types).strictbundle will eventually grow to include the entire library, and such that we can eventually add thegl2dandgl3dpartial bundles to the list of function-constructor-free bundles.strictbundle that doesn't happen to match what's inbasic,cartesian,finance,geo, ormapbox.nschloe commentedon Jun 16, 2021
Big thanks for releasing plotly-strict! This actually made it possible for me to use it in a browser extension for displaying plotly graphs in GitHub READMEs etc.:
This wasn't possible before because browser extensions disallow
eval()/function constructors.archmoj commentedon Jul 30, 2021
The number of function constructors were slightly higher that those initially listed above.
Namely
Function.applycalls were not catch byeslinttest.The list is now updated on #5869.
archmoj commentedon Sep 3, 2021
🎉 The v2.5.0 release removed calls to function constructor from various dependencies of
gl3dtraces as well asheatmapglandpointcloud.It is now possible to apply CSP directives e.g.
plotly.js/devtools/test_dashboard/index-strict.html
Line 4 in 8788e57
stackgl-basedtraces using"strict"or"gl3d"bundles.archmoj commentedon Mar 15, 2022
Addressed by various PRs. Now one could use the strict bundles e.g. https://www.npmjs.com/package/plotly.js-strict-dist-min
Update plotly-min.js (#954)