Urgent.News

What's breaking now, across thousands of outlets.

Tech

Why Does an NPM Math Library Need an Encrypted Loader?

A remote access implant was discovered concealed within the npm package [email protected], which is based on the well-known mathjs library. The malicious code is encrypted and remains inactive until a particular equation is solved using the library. This equation acts as the key to decrypt the payload, which is then executed on the host system.

The payload communicates with the attacker via a public chat service and a blockchain network. This report details how the loader was uncovered, decrypted, and what the payload does. The investigation began with a SafeDep analysis of the mathmain package on September 17, 2026. Although it appeared as a copy of mathjs with a different name and obfuscated code, the addition of a specific call in the solver led to the discovery of the loader.

The solver, in the function lusolve(), had an extra call that passed data from the lower triangular matrix to removeSolveValidation(). The isGraph() function within lib/cjs/utils/is.js decrypts and loads code. It converts the input to a JSON string, uses it as a password, decrypts a filename, and then loads the file with require().

The loader's decryption process uses scrypt to turn the password into a 256-bit key, which it then uses to decrypt the data with AES-GCM. The encrypted data includes a salt, an initialization vector, and an authentication tag. The package stores this data as base64 text. The password for the solver is JSON.stringify(L._data), meaning the caller must pass matrix data that produces the correct password.

No password is stored in the visible loader, but the encrypted filename hints at the existence of graph.js, a file in the same directory as the loader. Once the password is correct, the event() helper decrypts the file, writes the result to disk, and returns the output path. The require() call in isGraph() then loads the decrypted code, which runs with the same permissions as the Node.js process.

Three additional files contain base64 data that were not referenced in the visible loader. The decrypted graph.js loads these files as later stages in the payload. The npm registry contained two more packages: mathsbase and math-universe, all containing identical loader files, trigger code, solver changes, and large encrypted files.

These encrypted graphs.js differ from the others in version 1.0.1 of [email protected]. No install hooks were found in the manifest, and importing the package does not activate the loader unless the solver passes validation and calculation steps first. While no private code or a program using the solver was found, the investigation did not rule out the possibility of such instances existing.

Written by urgent.news from Hacker News's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at safedep.io →

More in Tech

More from Monday 21 September →