aframe icon indicating copy to clipboard operation
aframe copied to clipboard

Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script

Open samiemad opened this issue 3 years ago • 9 comments

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!

samiemad avatar Mar 21 '22 15:03 samiemad

Can you provide a link to an example to reproduce?

An example loading the library just fine: https://glitch.com/~aframe

dmarcos avatar Mar 21 '22 16:03 dmarcos

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

samiemad avatar Mar 28 '22 15:03 samiemad

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.

dmarcos avatar Mar 29 '22 01:03 dmarcos

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.

samiemad avatar Mar 30 '22 11:03 samiemad

Code is in https://github.com/Jam3/layout-bmfont-text/blob/master/index.js#L221

used by https://github.com/Jam3/three-bmfont-text

dmarcos avatar Mar 30 '22 21:03 dmarcos

The quickest option is probably make and serve your own A-Frame build with the code corrected / removed.

dmarcos avatar Mar 30 '22 21:03 dmarcos

Thanks. I'll have a look and see what I can do.

samiemad avatar Mar 31 '22 14:03 samiemad

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.

andrevenancio avatar Aug 19 '22 00:08 andrevenancio

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.

vincentfretin avatar Mar 31 '23 08:03 vincentfretin