Malicious npm math package hides encrypted remote access implant, triggered by a Pascal matrix
Why Does an NPM Math Library Need an Encrypted Loader?

SafeDep found a remote access implant in [email protected], an npm package copying mathjs. The encrypted loader activates only when lusolve() receives a specific 3x3 Pascal matrix, decrypting a payload that uses Slack and a blockchain testnet for command and control. The same loader appears in mathsbase and math-universe, with over 3 million combined downloads, though the GitHub source lacks the malicious code.
The password is the JSON form of L. A caller passes A to lusolve(). The solver runs an LU decomposition of A. The lower triangular factor L becomes [[1, 0, 0], [1, 1, 0], [1, 0.5, 1]]. The loader turns L into a JSON string. That string is the password.
- firesteelrain
What is the fix for npm at this point? It has a lot of issues with the registry
- fn-mote
You need to read quite a ways before discovering that JFrog did the work of cracking the password, which enabled the rest of the analysis.
- j2kun
Why in the world would that specific 3x3 matrix be a trigger for an attack? Are they trying to find someone doing some particular kind of numerical analysis?
- hiddenvulkcan
I actually came across someone that cracked it (or use Claude/China to crack it)
Turns out the second stage is completely broken, which is even more odd..
https://research.veryserious.systems/lusolve-and-you-shall-r...
- WorldMaker
A lot of this seems to be a reminder that the CommonJS module format should just be left to die already. Not that you can't pull similar tricks with `await import()` in ESM, but you can't easily grep an entire dependency for dynamic `require()` half as easily as you can can `grep import\s*\(` for dynamic import and analysis tools for static `import` keyword are easy to use/build rather than no such thing for CommonJS.
Someone thought I was joking when I said I always check JSR before NPM now, because I trust ESM so much more than CommonJS.