This article is about fixing Refuse to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in aframevr aframe
  • 20-Feb-2023
Lightrun Team
Author Lightrun Team
Share
This article is about fixing Refuse to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in aframevr aframe

Refused to evaluate a string as JavaScript because ‘unsafe-eval’ is not an allowed source of script in aframevr aframe

Lightrun Team
Lightrun Team
20-Feb-2023

Explanation of the problem

When loading a library, a browser may throw an error due to a Content Security Policy (CSP) directive that prohibits the use of ‘unsafe-eval’ as a source of script. In particular, aframe, a web framework for building virtual reality experiences, is known to require the use of ‘unsafe-eval’ to be allowed, which can be a security risk. In the following stack trace from the aframe-master.js file, the error is traced back to the use of Function constructor in the wrapper function, which violates the CSP policy.

function wrapper(name) {
  return (new Function([
    'return function '+name+'() {',
    '  return this._'+name,
    '}'
  ].join('\n')))()
}

To address the issue, one can replace the use of the Function constructor with a safer alternative. In the above code block, the Function constructor is used to generate a function that returns the value of a private variable of the TextLayout object. This can be replaced with a regular function definition that accesses the private variable directly, as shown below.

function addGetter(name) {
  Object.defineProperty(TextLayout.prototype, name, {
    get: function () {
      return this['_'+name]
    },
    configurable: true
  })
}

By using a simple function definition instead of the Function constructor, we can avoid the use of ‘unsafe-eval’ and comply with the CSP policy. However, this may require changes to the library code itself, and it may not always be possible or desirable to modify third-party code in this way. In such cases, alternative solutions such as setting up a separate CSP policy for the library may be considered.

Troubleshooting with the Lightrun Developer Observability Platform

Getting a sense of what’s actually happening inside a live application is a frustrating experience, one that relies mostly on querying and observing whatever logs were written during development.
Lightrun is a Developer Observability Platform, allowing developers to add telemetry to live applications in real-time, on-demand, and right from the IDE.

  • Instantly add logs to, set metrics in, and take snapshots of live applications
  • Insights delivered straight to your IDE or CLI
  • Works where you do: dev, QA, staging, CI/CD, and production

Start for free today

Problem solution for Refused to evaluate a string as JavaScript because ‘unsafe-eval’ is not an allowed source of script in aframevr aframe

To resolve the issue of ‘unsafe-eval’ being required for A-Frame and avoiding the security risks associated with it, there are a few possible solutions. One approach is to use the safe alternative to the Function constructor, which is the Function() constructor with arguments as strings. This can be achieved by modifying the code in the TextLayout prototype to replace the Function constructor with this safer alternative.

Here’s the modified code that avoids the use of the Function constructor:

//getters for the private vars
;['width', 'height', 
  'descender', 'ascender',
  'xHeight', 'baseline',
  'capHeight',
  'lineHeight' ].forEach(addGetter)

function addGetter(name) {
  Object.defineProperty(TextLayout.prototype, name, {
    get: function () {
      return this['_'+name]
    },
    configurable: true
  })
}

Another solution to this problem is to use a Content Security Policy (CSP) that allows the use of the ‘unsafe-eval’ directive. This involves adding the ‘unsafe-eval’ directive to the ‘script-src’ directive in the CSP. However, this approach is not recommended as it can introduce security vulnerabilities to the application.

A third solution is to use a pre-built version of A-Frame that does not require ‘unsafe-eval’. This can be achieved by using a production build of A-Frame, which has the Function constructor calls removed. The production build can be obtained from the A-Frame GitHub repository or by using a package manager like NPM. This approach is recommended as it ensures that the application is not exposed to the security risks associated with ‘unsafe-eval’.

Other popular problems with aframevr aframe

Problem: Refused to evaluate a string as JavaScript because ‘unsafe-eval’ is not an allowed source of script in A-Frame

When loading the A-Frame library in a web browser, an error may occur stating “Refused to evaluate a string as JavaScript because ‘unsafe-eval’ is not an allowed source of script”. This error occurs because the browser’s Content Security Policy directive does not allow the use of ‘unsafe-eval’, which is required by A-Frame.

Solution:

To work around this issue, there are several options. One option is to modify the Content Security Policy directive to allow ‘unsafe-eval’. However, this can be dangerous and is not recommended. Another option is to modify the A-Frame library to remove the use of ‘unsafe-eval’. For example, the code block in the original description could be replaced with a safer alternative, such as get: function () { return this['_'+name] }. Alternatively, a different library or framework that does not use ‘unsafe-eval’ could be used instead of A-Frame.

Problem: Inconsistent behavior across browsers

A-Frame may exhibit inconsistent behavior across different web browsers. For example, an A-Frame application that works correctly in Chrome may not work correctly in Firefox. This can be frustrating for developers and end-users, and can make it difficult to create applications that work reliably across different platforms.

Solution:

To address this issue, it is important to thoroughly test A-Frame applications in a variety of different web browsers. This can help identify any compatibility issues or inconsistencies, which can then be addressed by modifying the code or using different libraries or frameworks. It is also important to stay up-to-date with the latest versions of A-Frame and the web browsers being used, as updates can often address compatibility issues.

Problem: Limited support for advanced graphics and interactivity

While A-Frame provides a powerful platform for creating 3D and VR applications, it may not offer the same level of advanced graphics and interactivity as other libraries or frameworks. For example, A-Frame may not be able to handle complex animations or physics simulations, or may not provide the same level of control over user interactions as other platforms.

Solution:

To address this issue, it may be necessary to use additional libraries or frameworks in conjunction with A-Frame. For example, a physics engine like Cannon.js or Ammo.js could be used to add advanced physics simulations to an A-Frame application. Additionally, A-Frame can be used in conjunction with other libraries like Three.js to create more advanced graphics and animations. By using additional tools and frameworks, developers can take advantage of the strengths of A-Frame while still achieving the desired level of graphics and interactivity.

A brief introduction to in aframevr aframe

A-Frame is a popular web framework for building virtual reality experiences in the browser. It uses an entity-component-system (ECS) architecture that allows developers to create 3D scenes and interactive elements by composing reusable, modular components. A-Frame is built on top of Three.js, a popular 3D graphics library, and provides a higher-level API for creating VR experiences. It also has a growing ecosystem of community-created components and tools, making it a popular choice for both beginners and experienced developers.

One of the key features of A-Frame is its declarative HTML syntax. Developers can create VR scenes by adding HTML tags to their web pages, each of which corresponds to an A-Frame component. Components can be added to entities to provide functionality such as rendering a 3D model, playing a sound, or detecting user input. The declarative syntax allows developers to focus on the content and functionality of their VR experiences without having to worry about low-level details such as rendering and input handling. A-Frame also provides a JavaScript API for more advanced use cases, allowing developers to access and manipulate the underlying Three.js objects directly.

Most popular use cases for aframevr aframe

  1. VR/AR Experience Development: A-Frame is a popular open-source web framework for creating virtual reality (VR) and augmented reality (AR) experiences that run directly in the browser. It provides an easy-to-use, HTML-like markup language to create 3D scenes and objects, and it is based on the popular Three.js library. Here is an example of creating a box in A-Frame:
<a-box position="0 1 -3" rotation="0 45 45" color="#4CC3D9"></a-box>

This creates a blue box at position (0, 1, -3) with a rotation of (0, 45, 45).

  1. Interactive Web Applications: A-Frame can also be used to create interactive web applications that use VR/AR features. It allows developers to use HTML and JavaScript to create complex, interactive user interfaces that run in the browser. Here is an example of creating a button in A-Frame:
<a-entity button></a-entity>

This creates a button that can be interacted with by the user.

  1. Cross-Platform Development: A-Frame is designed to work on a variety of devices and platforms, including desktop and mobile web browsers, as well as VR and AR headsets. This makes it an ideal tool for developing cross-platform applications that can be used by a wide range of users. A-Frame also provides support for various VR/AR devices, such as the Oculus Rift and HTC Vive, and it is compatible with WebVR, the standard API for creating VR experiences in the browser.
Share

It’s Really not that Complicated.

You can actually understand what’s going on inside your live applications.

Try Lightrun’s Playground

Lets Talk!

Looking for more information about Lightrun and debugging?
We’d love to hear from you!
Drop us a line and we’ll get back to you shortly.

By submitting this form, I agree to Lightrun’s Privacy Policy and Terms of Use.