Discuss Scratch

apple502j
Scratcher
1000+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

On June 9th, 2020, me, apple502j, found a vulnerability in scratch-vm, a library used in Scratch 3.0 that handles project.json deserialization. This is patched on July 14th, and has a CVE ID of CVE-2020-14000.

Summary
A malicious project.json could load and execute arbitrary JavaScript file on the Internet.

Am I affected?
For most users, no. There is one thing that prevented it from happening on this website (scratch.mit.edu). However, if you are modding Scratch, it is likely that your mod is vulnerable to CVE-2020-14000.

Affected Versions
scratch-vm from 0.1.0-prerelease.1524239808 to 0.2.0-prerelease.20200709173451 (both inclusive). This is patched in 0.2.0-prerelease.20200714185213.

Note that this only affects environments that has Web Workers enabled. If you don't serve the web worker file (extension-worker.js), you are not affected. This is the case for the scratch.mit.edu.

How to Fix
If you can, upgrade your scratch-vm to 0.2.0-prerelease.20200714185213. If you cannot, apply changes made in the pull request.

Causes
When a project with extension loads, it passes the project.json's “opcode” field to a function called getExtensionIdForOpcode. This splits the opcode by underscore and returns the first part. This is a project.json with pen extension blocks:


It will return “pen”. For most blocks, the first part is extension ID, so this is fine. But, what if, I crafted a project.json so that getExtensionIdForOpcode returns a URL?


The returned value for getExtensionIdForOpcode goes to VirtualMachine.installTargets which loads the extension using a function called loadExtensionURL.

getExtensionIdForOpcode didn't have sanitation or validation, so the returned URL - https://apple502j.github.io/files/SheepMakerUtil.js - is passed to loadExtensionURL. In ExtensionManager.loadExtensionURL, first it checks if the ID is in “built-in extensions” list - which isn't (obviously, it's an URL, not ID) and then, it allocates a Web Worker for the extension, and tells it to load the JavaScript file.

Inside ExtensionWorker we have importScripts - which loads the JavaScript file. This is loaded inside Web Worker, so attackers can only do stuff that Web Workers can - but it is definitely not an intended behavior, and can be considered a vulnerability.

Timeline
  • June 9th: discovered this vulnerability
  • June 9th: contacted the Scratch Team
  • June 10th: obtained a CVE ID
  • June 10th: notified the Scratch Team about the CVE ID
  • June 10th: notified npm about the vulnerability
  • June 12th: notified the Scratch Team about the vulnerability again, got response
  • June 12th: npm's response
  • June 15th: pull request https://github.com/LLK/scratch-vm/pull/2476 created
  • July 1st: sent a proof-of-concept file to the ST
  • July 14th: PR merged, disclosing
novice27b
Scratcher
1000+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

Congrats!

You got the CVE assigned very quickly, what process did you have to go through to apply for one?
apple502j
Scratcher
1000+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

novice27b wrote:

Congrats!

You got the CVE assigned very quickly, what process did you have to go through to apply for one?
I just filled MITRE's form. It seems like it's actually harder to get ST's attention than MITRE's.
SausageMcSauce
Scratcher
1000+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

Is there any mention of the vulnerability outside of Scratch and the scratch-vm repository?
apple502j
Scratcher
1000+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

SausageMcSauce wrote:

Is there any mention of the vulnerability outside of Scratch and the scratch-vm repository?
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14000 should soon be updated.
novice27b
Scratcher
1000+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

apple502j wrote:

novice27b wrote:

Congrats!

You got the CVE assigned very quickly, what process did you have to go through to apply for one?
I just filled MITRE's form. It seems like it's actually harder to get ST's attention than MITRE's.
Yeah, I've had mixed experiences with reporting vulnerabilities to the scratch team.

If anyone from the team is reading this, please set up a dedicated security email address (ideally with a pgp pubkey available too).
noverify
Scratcher
15 posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

Very interesting that scratch just allowed to load an url out of nowhere!
apple502j
Scratcher
1000+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

Capitan_Florida_2
Scratcher
100+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

apple502j wrote:

The CVE entry is published at https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14000
woah that's crazy
show me a test of it
herohamp
Scratcher
1000+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

So who does this apply to then if it does not apply to Scratch?
A-E-
Scratcher
100+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

herohamp wrote:

So who does this apply to then if it does not apply to Scratch?
It applies to mods with extention support, though many such mods allow loading from URLs anyway.
ElsieBreeze
Scratcher
100+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

herohamp wrote:

So who does this apply to then if it does not apply to Scratch?
I'd imagine Scratch Mods that use workers, as I imagine some might do.
Boomer001
Scratcher
1000+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

Wow, reading this scared me…
I'm happy it's patched!
EDIT: was able to repro here.

Last edited by Boomer001 (July 18, 2020 09:59:42)

apple502j
Scratcher
1000+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

CVSS v3.1 Scores
By my calculation: 6.1 (Medium) - CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
Attack Vendor: Network - scratch-vm is (in most cases) used in web applications.
Attack Complexity: Low - One crafted file can be reused indefinitely, and nothing complicated.
Privileges Required: None - Anyone can load a .sb3 file.
User Interaction: Required - Victims need to load crafted .sb3 files.
Scope: Changed - While the techniques are not the same, the results are the same as Cross-Site Scripting, but in a sandboxed worker.
Confidentiality: Some information that can be accessed inside an worker can be obtained.
Integrity: Attackers can modify data (for example, send fetch() requests)
Availability: None - While not impossible, it is very hard to crash the computer.

Here are some of the scores provided by third parties:
- NVD: 9.8(Critical) - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
To be honest, this is too big. You know, it's not OS command injection or something.

- Snyk: 2.9(Low) - CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L
Attack Complexity and User Interaction seems incorrect.
AmazingMech2418
Scratcher
1000+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

Wouldn't the system for loading from a URL be used for extensions? Also, this is not really a huge deal unless it can access storage and/or cookies though. The best way to sanitize the input would probably to use an allowlist for domains instead of just sanitizing any URLs.
apple502j
Scratcher
1000+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

This is not the intended mechanics, because getExtensionIdForOpcode is, well… for getting extension ID and not opcode. Ability to make fetch() request itself is enough to be considered as a vulnerability.
AmazingMech2418
Scratcher
1000+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

apple502j wrote:

This is not the intended mechanics, because getExtensionIdForOpcode is, well… for getting extension ID and not opcode. Ability to make fetch() request itself is enough to be considered as a vulnerability.
Why would there be loadExtensionURL function then that is called by getExtensionIdForOpcode? If it weren't for including extensions not directly in scratch-vm, it must be for loading extensions from URLs. Also, it is sandboxed, so even a fetch request wouldn't be too bad. It's really kind of like the experimental extensions in Scratch 2.0 except that it automatically loads the extension instead of you having to copy and paste into the console.
apple502j
Scratcher
1000+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

I think this is because developers either wanted to add “extension URL” field to project.json (but they didn't) - or too lazy to promisify sync API. The problem is there is no warning or similar stuff before loading such extensions.
Sheep_maker
Scratcher
1000+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

AmazingMech2418 wrote:

Also, it is sandboxed, so even a fetch request wouldn't be too bad.
Perhaps it could be used to DDOS a target if a project abusing this got popular by just constantly spamming requests from every user with the project open. Alternatively, it could be used to spam requests from a different IP (if CORS were enabled on the target).

I think cryptocurrency miners can also be run inside a web worker if they're just math and a bunch of requests
AmazingMech2418
Scratcher
1000+ posts

CVE-2020-14000: Script Injection vulnerability in scratch-vm

Sheep_maker wrote:

AmazingMech2418 wrote:

Also, it is sandboxed, so even a fetch request wouldn't be too bad.
Perhaps it could be used to DDOS a target if a project abusing this got popular by just constantly spamming requests from every user with the project open. Alternatively, it could be used to spam requests from a different IP (if CORS were enabled on the target).

I think cryptocurrency miners can also be run inside a web worker if they're just math and a bunch of requests
Yeah, but, again, CORS would have to be enabled on the target and most largely targeted websites have CORS disabled as is the default normally.

Powered by DjangoBB