question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

PIXI requires unsafe CSP

See original GitHub issue

Expected Behavior

PIXI.js works with a strict CSP (e.g. script-src 'self') by default.

Current Behavior

PIXI.js requires an external module that patches it in order to work with strict CSP (@pixi/unsafe-eval). Not being safe by default opens a number of attack vectors on the application of the developer:

  • Opens the door to XSS due to PIXI itself. Even if today your use of new Function is safe (has anyone conducted a security audit recently?), as code evolves, there is a significant risk that an XSS vulnerability will be introduced by accident.
  • A relaxed CSP allowing unsafe eval can’t be applied just to PIXI (as far as I know, let me know otherwise), so because of PIXI, the unsafe eval behavior has to be allowed on the entire app. While PIXI engineers can, to some extent, be confident in the security of the PIXI library, you can’t be confident about any other code landing on the final application of the developer.

The whole point of CSP is to deal with situations in which you can’t reliably ensure the quality of all the sources being pulled into your final application.

Possible Solution

Make @pixi/unsafe-eval the default behavior of PIXI.js, and instead create an external module to make PIXI faster for those devs who need the extra speed and know what they are doing. Most likely, the majority of developers won’t need the extra speed, but their end users will appreciate the extra security.

Steps to Reproduce

Add a strict CSP meta tag to your HTML (or a header):

  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">

Run a PIXI-based application.

Environment

  • pixi.js version: 5.3.8
  • Browser & Version: Chrome 89
  • OS & Version: Ubuntu 20.04.2
  • Running Example: n/a

Related: #5509

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:2
  • Comments:13 (7 by maintainers)

github_iconTop GitHub Comments

4reactions
qtikicommented, May 22, 2021

I just ran into this issue as well while upgrading the security of our CDN. One thing I’d like to add to this is that even with the @pixi/unsafe-eval package the try/catch detection causes a CSP violation. This is hidden from the console logs but if you use any of the reporting directives, like report-to, report-uri, or the Content-Security-Policy-Report-Only header this violation will get logged. In essence this means you’ll get a violation report from every user loading the app.

I am confident that PIXI’s use of new Function is pretty much safe but I don’t really like that in order to enable that you will basically have to allow unsafe eval for all scripts on your site.

One other option for the future might be the strict-dynamic directive. That should allow trusted scripts to run arbitrary generated code. The documentation shows an example of the script add a new <script> tag dynamically. I’m not 100% sure if that applies to eval and new Function as well. However this is not supported in some common browsers yet (like Safari) so I guess we’ll have to wait and see how it goes.

Also while testing this with the require-trusted-types-for header I found out that Chrome’s trusted Function implementation has a bug which causes even more headache for PIXI’s new Function usage - in essence it won’t work without that workaround even with the @pixi/unsafe-eval package.

I think @SukantPal’s idea for a long term solutions sounds good - I was thinking of something similar before landing on this issue. This would really make all of this discussion irrelevant since it all boils down to the runtime usage of new Function:

Yeah, I don’t think we’ll switch this in the foreseeable future. A long term solution would be to generate uniform uploading functions at compile time.

And while I agree in principle with @ivanpopelyshev’s comment about using the language features I have to point out that some language features turn out to be mistakes later on and will get deprecated (or blocked by security features):

But, what is the point of using JS if we dont use its features?

All that said, we will be sticking with the allow unsafe-eval CSP directive for now as the world doesn’t seem ready for a more secure configuration with PIXI yet. As a fix for the CSP violation reporting spam it would probably make sense to add a “force” parameter to the unsafe-eval install function so the detection can be skipped in scenarios where you know it won’t be allowed.

4reactions
rubenlgcommented, Mar 23, 2021

Don’t get me wrong. I love PIXI. I’ve been writing raw WebGL pretty much since it came out 10 years ago, and PIXI changed completely the way I write games and especially level editors, allowing me to focus on the app logic rather than fighting the GL state machine. It’s comparable to what OpenSceneGraph did to my code back in the 90s, when I could stop writing raw OpenGL for C++. Thanks a lot for your work!

I understand that there is a trade-off between performance and security. My argument is that by default any web library, including PIXI, should favor security by default, especially when the developer has explicitly enabled CSP because they care, and fall back to performance upon conscious choice by the developer.

Right now, whenever a user has a strict CSP, PIXI just doesn’t work. The developer gets a helpful message in the console, but all of the sudden, they are forced to choose between installing an extra module that will make their app slower, or relaxing their CSP. Guess what, most junior developers when faced with that dilemma, blindly choose performance, because they are unable to gauge whether the performance degradation matters at all to their app/game, and loosing frames seems like a much more tangible risk than having an XSS bug in their “perfect” app/game code.

Here is another alternative:

You already do feature detection in order to show that use @pixi/unsafe-eval message. What if instead of failing with that message, you automatically enable safe+slow mode when you detect a disabled eval (maybe with a console warning about performance implications) and run in unsafe+fast mode whenever eval is allowed?

That way, PIXI would always work regardless of the CSP setting, and people without performance issues wouldn’t need to worry about it at all. Does that sound like a reasonable trade-off?

Read more comments on GitHub >

github_iconTop Results From Across the Web

PIXI requires unsafe CSP · Issue #7324 · pixijs/pixijs - GitHub
PIXI.js requires an external module that patches it in order to work with strict CSP ( @pixi/unsafe-eval ). Not being safe by default...
Read more >
Electron, PixiJS, and Content Security Policy - Reddit
Uncaught Error: Current environment does not allow unsafe-eval, please use @pixi/unsafe-eval module to enable support. at ShaderSystem.
Read more >
Content-Security-Policy and browser injection
I'm working on setting up CSP (which prevents inlines scripts from running) on our web app, to mitigate XSS. At present, we inject...
Read more >
How to fix "unsafe-eval" error with Vue3 for the client-side ...
The problem is that when I use it, it keeps giving me an Uncaught EvalError: Refused to evaluate a string as JavaScript because...
Read more >
Strict CSP - Content Security Policy
To enable a strict CSP policy, most applications will need to make the ... script-src nonce-{random} 'unsafe-inline' The nonce directive means that <script> ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found