aframe
aframe copied to clipboard
Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script
Description: When loading the library, the browser throws an error:
Uncaught 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' [...]"
Looking into the stack trace, I see these lines from https://github.com/aframevr/aframe/blob/master/dist/aframe-master.js
//getters for the private vars
;['width', 'height',
'descender', 'ascender',
'xHeight', 'baseline',
'capHeight',
'lineHeight' ].forEach(addGetter)
function addGetter(name) {
Object.defineProperty(TextLayout.prototype, name, {
get: wrapper(name),
configurable: true
})
}
//create lookups for private vars
function wrapper(name) {
return (new Function([
'return function '+name+'() {',
' return this._'+name,
'}'
].join('\n')))()
}
Looks like aframe requires unsafe-eval to be allowed which is quite dangerous. Is there a workaround to use aframe without enabling unsafe-eval??
Can this be replaced by something safer? like:
get: function () {
return this['_'+name]
},
- A-Frame Version: 1.3.0
- Platform / Device: PC / Chrome
- Reproducible Code Snippet or URL:
Thanks!
Can you provide a link to an example to reproduce?
An example loading the library just fine: https://glitch.com/~aframe
Yes sure. Adding the content security policy breaks it.
Here is the code to reproduce: https://glitch.com/edit/#!/few-coherent-guilty?previewSize=0&attributionHidden=false&sidebarCollapsed=false&path=&previewFirst=false
<!DOCTYPE html>
<html>
<head>
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self' https://aframe.io;
style-src 'self' 'unsafe-inline';"
/>
<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
</head>
<body>
<a-scene>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder
position="1 0.75 -3"
radius="0.5"
height="1.5"
color="#FFC65D"
></a-cylinder>
<a-plane
position="0 0 -4"
rotation="-90 0 0"
width="4"
height="4"
color="#7BC8A4"
></a-plane>
<a-sky color="#ECECEC"></a-sky>
</a-scene>
</body>
</html>
After adding unsafe-eval to script-src 'self' https://aframe.io;, the page loads without problems
Do you need that meta tag? FWIW the unsafe-eval code you pointed comes from a dependency bet seems safe. Just adding getters automatically to the object.
Yes, I agree it seems safe. But this setting is global. So if we allow it, it will be allowed for the whole web app and makes the whole app security lower. After all it's called unsafe for a reason.
OTOH, since it's a simple use-case of adding getters, it should not be too hard to replace with something safer, right?
Anyway, if you help me track that dependency I would be happy to try to fix the issue and create a PR.
Code is in https://github.com/Jam3/layout-bmfont-text/blob/master/index.js#L221
used by https://github.com/Jam3/three-bmfont-text
The quickest option is probably make and serve your own A-Frame build with the code corrected / removed.
Thanks. I'll have a look and see what I can do.
Hey @mattdesl Its been a while but has anyone updated this dependency on Jam3 side? Some providers just block content if there is an eval on the code.
Cloudflare does it, and causes issues loading on web3 platforms.
Here's an example with NFTStorage IPFS Gateway: https://bafybeidg3y34lewgcbarxgq4sayiwnl2lpb4smvxsic7cmzthv2rlov6de.ipfs.nftstorage.link/
And the same example with IPFS.IO Gateway: https://ipfs.io/ipfs/QmVGCppbY5cQ7XUqNzUS51uV4usS51UEzEQzpQ3ZLXh3NG/
The NFTStorage one uses cloudflare, and they do not allow evals as they allow for malicious code to be injected on the client.
Someone on slack had the same error trying to embed aframe into a chrome extension where unsafe-eval is forbidden.
If the issue is in the layout-bmfont-text dependency you can probably create your own aframe build without the text component by commenting the line require('./text'); in src/components/index.js (I have not tested it) and use some other component like https://github.com/lojjic/aframe-troika-text if you need to show some text.