Closed feugy closed 2 years ago
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.
It doesn't look like plotly uses the cwise browserify transform when bundling plotly.js,
The plotly build step doesn't explicitly list the cwise
transform, but several of our dependencies have cwise
listed in their respective package.json namely ndarray-fill
, ndarray-wrap
and gl-select-static
(ref this script).
I'm also running into this problem. Can't run my (Meteor) app because of this. Is there a work-around maybe?
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?
Still seeing this as well. Hasn't been addressed at all.
Nothing has changed since https://github.com/plotly/plotly.js/issues/897#issuecomment-244402532, so yes this hasn't been addressed at all :scream:
The problematic cwise
transform is only used in gl3d and gl2d (excluding scattergl
), 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.
Thanks for the advice! I'll take a look at that.
Does anyone have the CSP header they've used to keep security as tight as possible but still use plotly?
@jtal
Does anyone have the CSP header they've used to keep security as tight as possible but still use plotly?
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
Looks like the direct plotly.js
dependencies today that make plotly.js
dependent on cwise
are:
Does anyone know if it is feasible for plotly.js
to go away from these dependencies (any alternatives?) and/or modify the dependencies themselves to not use cwise
?
The unsafe-eval
requirement is unfortunately currently stopping us from being allowed to use plotly.js
's variant of parallell coordinates, as it appears to be part of the gl2d
bundle, which then looks to be indirectly requiring cwise
, ref. https://github.com/plotly/plotly.js/issues/897#issuecomment-371968332.
@anders-kiaer you may be interested in https://www.npmjs.com/package/plotly.js-gl2d-dist, you can install it using
npm install plotly.js-gl2d-dist
which has no dependencies.
Thanks @etpinard 🙂 Hmm, not sure if I understand, isn't the cwise
dependency bundled into the gl2d
dist? I tried using the dist from npm 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:
import dash
import dash_html_components as html
from flask_talisman import Talisman
app = dash.Dash(
__name__, external_scripts=["https://cdn.plot.ly/plotly-gl2d-latest.min.js"]
)
CSP = {
"default-src": "'self'",
"script-src": [
"'self'",
"https://cdn.plot.ly",
# "'unsafe-eval'",
"'sha256-jZlsGVOhUAIcH+4PVs7QuGZkthRMgvT2n0ilH6/zTM0='",
],
"style-src": ["'self'", "'unsafe-inline'"],
}
Talisman(app.server, content_security_policy=CSP, force_https=False)
app.layout = html.Span("Hello Dash!")
if __name__ == "__main__":
app.run_server()
which when looking at the browser console gives a
EvalError: call to Function() blocked by CSP
unless 'unsafe-eval'
is added. Searching through plotly-gl2d.js
gives me 18 hits on Function(
. The first hit looks to come from this line.
My mistake. I thought you were worried about the "unsafe-eval" behavior of cwise
when 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.
But, the basic
, cartesian
, geo
, mapbox
and finance
partial bundles should be fine.
That is, bundles that include trace types other than gl3d
, gl2d
, scattergl
and splom
should pass the "unsafe-eval" checks.
FWIW I don't think it would be unreasonable to explore making an eval-free version of cwise
- it's not the eval
that gives it its speed, it's just using that to do codegen and reduce its own size. But at the end of the day I'd expect gzip means this codegen isn't even saving that many bytes over the wire... not a guarantee, but if someone wants to explore that we would certainly entertain it.
The current version 1.52.2 (https://raw.githubusercontent.com/plotly/plotly.js/v1.52.2/dist/plotly.js) uses Fonction
in eval mode in those places:
compileBoundsSearch
from https://github.com/mikolalysenko/binary-search-bounds can be fixed by https://github.com/mikolalysenko/binary-search-bounds/pull/8 (Using a fork of this package will not be useful as the package using it is from the same author)bruteForcePlanner
from https://github.com/mikolalysenko/box-intersect (an issue is opened: https://github.com/mikolalysenko/box-intersect/issues/6) required by clean-pslg compileBoundsSearch
again (!) (probably two different version of binary-search-bounds required by two different packages...)generateCWiseOp
and L18128 in createThunk
from https://github.com/scijs/cwise-compiler/ required by cwise, ndarray-gradient, ndarray-* and zero-crossings. Doesn't look fixable...dsv.parseRows
will not be fixed https://github.com/d3/d3-fetch/issues/35#issuecomment-586739138 but it only impact Plotly.d3.csv/tsv/dsv methods.polyfill
but that line should never be reached in browser context so it's fine.identity
: https://github.com/stackgl/gl-shader/issues/21makeGetter
: https://github.com/stackgl/gl-shader/issues/21makeSetter
: https://github.com/stackgl/gl-shader/issues/21bakeOrient
compileSurfaceProcedure
pcompile
createInsertionSort
createQuickSort
compileSort
compileConstructor
compileDeterminant
orientation
generateSolver
orientation
(bis)createCellPolygonizer
buildSurfaceNets
Looks like the direct
plotly.js
dependencies today that makeplotly.js
dependent oncwise
are:Does anyone know if it is feasible for
plotly.js
to go away from these dependencies (any alternatives?) and/or modify the dependencies themselves to not usecwise
?
@anders-kiaer this is done in #4929 and #4930 and available in plotly.js >= v1.54.4
We're still meeting the use of eval as a problem trying to integrate plotly.js within CryptPad. Using smaller ones as anders suggested (in https://github.com/plotly/plotly.js/issues/897#issuecomment-585315283 did not solve it for us).
A pity...
@polx can you confirm this is happening with version 1.54.7 of plotly.js, and can you provide some context around what tool you're using that is complaining about this please? This issue has wandered all over the place since 2016 and we recently addressed parts of it but it's not clear what's outstanding. It might be helpful to create a new issue narrowly-scope to the problem you're seeing.
Hello @nicolaskruchten , Yes, it was on 1.54.7. We've been trying to embed plotly renderings as one of the rendering "macros" for cryptpad code (https://cryptpad.fr/). Cryptpad aimst at very high security standard and thus requires CSP. If we deactivate CSP, then things load. If we activate CSP then I get the following having replaced the plotly with the non-minimized version.
Uncaught EvalError: call to Function() blocked by CSP
makeOp http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:60786
[443]</< http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:60808
[443]< http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:60835
o http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:7
o http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:7
[253]< http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:41713
o http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:7
o http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:7
[266]< http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:44060
o http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:7
o http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:7
[1164]< http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:190058
o http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:7
o http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:7
[1166]< http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:190689
o http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:7
o http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:7
[36]< http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:614
o http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:7
o http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:7
[26]< http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:420
o http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:7
r http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:7
<anonymous> http://localhost:3000/lib/plotly-latest.min.js?ver=3.20.1-1596722563915:7
execCb http://localhost:3001/bower_components/requirejs/require.js?ver=2.3.5:1696
Does it help?
Paul
@anders-kiaer this is done in #4929 and #4930 and available in plotly.js >= v1.54.4
I'm also still experiencing this eval error with v1.54.7 @nicolaskruchten both pages are HTML and one is using the CDN and the other one has v1.54.7 in a Githubissues.
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:
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 ?