Binky. The name haunted me as as I stared at it and pondered what could have brought this to be. Socket's analysis scans all versions of a package when it finds something unusual, and Binky was definitely not usual. Imagine publishing a new version of a package every day for 30 years. That is less than the number of versions of Binky in the npm registry. At the time of writing this, Binky currently sits at 11,460 versions in the public npm registry.
Does the package actually do anything? Its name seems to be a reference to an animated kids show and has an image to reinforce that in the readme. In its README.md
it claims:
Binky.js is the pinnacle of contemporary research and innovation in the field of computer science. Using a GPU cluster located in South Ohio, Binky.js is able to precisely determine the binkiness of objects. Being sentient, Binky.js is able to even determine the object in question.
This is a lie, but the truth is a bit more confusing. What on earth could lead to this many versions? Binky is a fairly small package. Sitting at 31 lines total it isn't too hard to understand, 20 of which are in README.md
which we can skip.
test.txt
is apparently used as a template for package.json
and contains (UTF-16 BOM removed here):
{"name":"binky","version":"3.2.$counter","bin":{"binky":"./bin/binky.js"},"dependencies":{"random-seed":"^0.3.0"}}
No line breaks, small enough to understand, no install scripts or trickery. This isn't going to act like a worm and propagate automatically.
But, it does have a bin script:
#!/usr/bin/env node
let p=process.argv,l=console.log;l(p.includes("--help")?"Run binky <thing> to check binkiness!":require("random-seed").create(p).random()?"This is binky \uD83D\uDC4D":"This is not binky.");
In 2 lines of code (the escape just is for the 👍 emoji), it just appears to call out to the random-seed
package and print a message; maybe I would find answers there I hoped. Luckily, that package only has 3 versions, the last of which was from 7 years ago.
Still hunting for if this package is somehow invoking npm and propagating we can read though random-seed's source. random-seed depends on only 1 non-dev dependency which would be the standard installation of it: json-stringify-safe
which is completely normal and comes from well known maintainers.
However, we look into random-seed itself and see that its source is like something spit out by ChatGPT. It has beautiful comments but largely just looks slightly off in today's modern JS. It is a pseudo-random number generator and does even link to the origin of most of the source from the Gibson Research Corporation, but it is just a simple update if you look at it; nothing to do with the massive amount of binky versions.
Looking at other files lying around we find an upload.ps1
file in the root of the package.
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
$PAR1 = '{"name":"binky","version":"3.5.'
$PAR2 = '","bin":{"binky":"./bin/binky.js"},"dependencies":{"random-seed":"^0.3.0"}}'
$counter = 314
while($true) {
echo "$PAR1$counter$PAR2" > package.json
npm publish
$counter++
}%
A PowerShell script. The test.txt
template is unused for whatever reason, and instead it's using string concatenation then looping forever - trying to publish package versions one after another. The counter variable is a bit out of date, but at these version counts it isn't too far off.
npm limits how quickly a person can publish things to the public registry, so how long ago did this start? The first version came out 4 months ago at 2022-09-12T08:48:41.727Z
. Since then, it has averaged publishing a version every 1000 seconds approximately at time of this writing. The versions aren't increasing anymore, presumably because the script hasn't been running; but it certainly is an example of the wild things people do to the npm registry.