Where did these mysterious PrismJS npm versions come from?
Tags: security, programming, javascript, opensource
Published: 2021-04-16 06:49:02

In 2015, strange `9000.0.x` versions of *PrismJS* appeared on npm downloads, and nobody had a clue where they came from, or what purpose they served.

Roughly four years later, PrismJS `9000.0.1` and `9000.0.2` were removed from npm for the reasons described below.

But to date, no one seems to know anything more about this incident.

PrismJS is a lightweight, robust, and elegant syntax highlighting library that is based on *[Dabblet](https://dabblet.com/)*.

![](https://securityreport.com/wp-content/uploads/2021/04/image-6-1024x535.png)

Its sheer popularity among developers is demonstrated by the **4.5 million weekly downloads** PrismJS receives on the npm registry.

Prism is also the choice of the library for websites of famous tech brands like Stripe, Drupal, MySQL, React, etc.

![](https://securityreport.com/wp-content/uploads/2021/04/image-5-1024x447.png)

Image source: prismjs.com

## So, who published Prism 9000.0.x?

In November 2015, [Rob Loach](https://twitter.com/RobLoach), a developer raised concerns about strange versions 9000.0.1 and 9000.0.2 that had appeared on npm.

Versions 9000.0.x published on 12th May, 2015, stood out as, at the time, the latest version of PrismJS was **1.3.0**.

Also, the very first version 0.0.1 had been published on 13th May, 2015, so how come, the timestamp data from npm show 9000.0.x versions having been published a day prior to the initial release?

```javascript
{ "name": "prismjs",  
"dist-tags": { "latest": "1.3.0" },  
"versions": \[ "0.0.1", "1.1.0", "1.2.0", "1.3.0", "9000.0.1" \],  
"time":  
{  
"9000.0.1": "2015-05-12T23:54:40.643Z",  
"9000.0.2": "2015-05-12T23:56:14.033Z",  
"0.0.1": "2015-05-13T00:37:38.541Z",  
"1.1.0": "2015-10-06T00:03:04.995Z",  
"1.2.0": "2015-10-07T17:35:20.776Z",  
"1.3.0": "2015-10-27T02:35:27.738Z" }  
}
```

Loach raised a GitHub issue for the maintainers of PrismJS to [unpublish these “broken” versions from npm](https://github.com/prismjs/prism/issues/819), and this is where it gets interesting.

PrismJS creator and an elected W3C member, [Lea Verou](https://twitter.com/leaverou) asked another web developer at the time, “any ideas where the 9000 came from? Is it safe to remove?”

By July 2016, [*Golmote*](https://twitter.com/golmote?lang=en), a contributor to the PrismJS project responded with:  
“I don’t know where those weird versions come from. They are dated at the time of the creation of the NPM package… so I guess they may have been mistakes, or automatically created maybe?”

![](https://securityreport.com/wp-content/uploads/2021/04/image-8-1024x330.png)

Image source: GitHub issue

The chatter continued in the same thread for quite some time as access issues were being sorted—that is, maintainers trying to figure out who had access to PrismJS’ npm account.

Finally, npm was notified and began taking these 9000.0.x versions down sometime in October 2019.

## A dependency confusion attack?

A particularly interesting incidence here is the choice of large version numbers itself: *9000.0.1* and *9000.0.2*.

These version numbers of PrismJS were causing problems for some developers:

“Removing this would be great as it will help to keep a consistent versioning,” said software developer Harald Nezbeda at the time.

“Currently, this is causing also **confusion** in services… Updating to the latest version of the **dependencies** causes it to take 9000.0.1,” Nezbeda continued.

Another open-source CLI tool called *updates*, which checks for npm dependency updates, had to [rewrite](https://github.com/silverwind/updates/issues/13) its version resolution logic to *not* pull the 9000.0.x versions.

Earlier this year, I broke news on how a researcher [hacked over 35 big tech firms](https://www.bleepingcomputer.com/news/security/researcher-hacks-over-35-tech-firms-in-novel-supply-chain-attack/) and earned over $130,000 in bug bounties by exploiting a novel kind of open-source supply chain weakness, called [dependency confusion](https://www.bleepingcomputer.com/news/security/researcher-hacks-over-35-tech-firms-in-novel-supply-chain-attack/).

Incidentally, the said researcher, Alex Birsan, mentions using an example **9000.0.0** version in his proof-of-concept (PoC) dependency confusion demos, in his [blog post](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610?sk=991ef9a180558d25c5c6bc5081c99089) released this February.

Other bug bounty hunters have used 9000.0.x versions in their copycat PoC demos as well \[[1](https://libraries.io/pypi/doxygen/9000.0.1), [2](https://pypi.org/project/kubectl/9000.0.1/)\].

But the exact mechanics behind how conflicting dependency names and higher-numbered versions in open-source ecosystems that lack proper namespacing can be troublesome have been known to the developer community years before *dependency confusion* attacks made “news.”

“If I know of a package in use by a company through log analysis, bug report analysis, etc., I could potentially go register the same name in the default repo with a very high \[semantic version\] and know that it’s very likely that this would be picked up over the intended, internally developed module because there’s no namespace,” Sonatype CTO Brian Fox had said in his 2017 [writeup](https://dzone.com/articles/java-automodules-considered-bad-for-your-health).

In 2015 alone, for example, RubyGems had [deleted](https://rubygems.org/gems/rails-assets-angular/versions/9000.0.0) a 9000.0.0 version of *rails-assets-angular.*

**Why**? Because it was [malicious](https://github.com/rubygems/rubygems/issues/1148). Somebody had used it to pull a successful dependency confusion attack:

“Someone used bundler’s [CVE-2013-0334](http://bundler.io/blog/2014/08/14/bundler-may-install-gems-from-a-different-source-than-expected-cve-2013-0334.html) to perform \[an\]attack on our service and created *rails-assets-angular* gem with the same name as on our service.”

“Now every time someone \[runs\] `bundle update`, the RubyGems gem is installed instead of ours,” [said](https://github.com/rubygems/rubygems.org/issues/857) developer, Adam Stankiewicz, who represents the official rails-assets.org service.

## What is inside 9000.0.x versions?

But, what about the PrismJS 9000.0.x versions?

Although these versions have been pulled from npm downloads, and the entirety of the internet for good, I was able to dig into Sonatype’s automated malware detection system archives to retrieve a copy of the 9000.0.1 version:

![](https://securityreport.com/wp-content/uploads/2021/04/image-10-1024x551.png)

The now-removed PrismJS version 9000.0.1 (Image source: Security Report)

While analysis is still ongoing, so far, there is no indication of any malicious code or exploit embedded within PrismJS 9000.0.1.

Considering, nobody—including PrismJS developers, knows where these weird 9000.0.1 and 9000.0.2 versions had come from, it is plausible that an attempted supply-chain attack was caught and subverted in time before the author of these 9000.0.x versions had managed to publish an outright malicious PrismJS version.

Still, the 9000.0.x versions did make their way into development builds of at least some open-source projects, inconveniencing their maintainers.

Fast-forward to 2021, dependency confusion attacks are being [actively leveraged](https://blog.sonatype.com/malicious-dependency-confusion-copycats-exfiltrate-bash-history-and-etc-shadow-files) to target software projects named after renowned brands like Amazon, Slack, Zillow, and Lyft.

Moreover, novel brandjacking and typosquatting supply chain attacks are on the rise, like the [newly discovered Linux and macOS malware](https://blog.sonatype.com/damaging-linux-mac-malware-bundled-within-browserify-npm-brandjack-attempt) hidden within a counterfeit component named after “Browserify”.

As these attacks continue to grow, it is worth checking your software development builds for suspicious dependencies, malicious components, and install [automation solutions](https://blog.sonatype.com/sonatype-releases-new-nexus-firewall-policy-to-secure-software-supply-chains-from-dependency-confusion-attacks) that can proactively detect and block these attacks from compromising your software builds.

Syndicated from [*securityreport.com*](https://securityreport.com/where-did-these-mysterious-prismjs-npm-versions-come-from/)