Back
SafeDep finds an encrypted loader inside the npm math library mathmain
SiTech AI Team3 წთ. საკითხავი

SafeDep finds an encrypted loader inside the npm math library mathmain

Researchers at SafeDep found a loader for encrypted code in the npm package mathmain. It takes its password from data passed to the solver, and it can write and run a decrypted file.

Researchers at SafeDep have found a loader for encrypted code inside mathmain, an npm package presented as a mathematics library. The loader takes its password from data passed to the library's matrix solver, and with the right input it can decrypt a file and run the code inside it. The analysis was published on 17 September 2026; the encrypted payload itself could not be decrypted.

A hidden call inside the solver

SafeDep began from the observation that mathmain looked like a renamed, obfuscated copy of the widely used mathjs library. The clue was one extra call near the end of lusolve() in the CommonJS build: after computing its result, the solver passes data from the lower triangular matrix to removeSolveValidation() and never uses the returned value.

That call resolves to isGraph() in lib/cjs/utils/is.js. isGraph() turns its input into a JSON string and uses it as a password, decrypts a file name from a base64 blob, then passes the path and the password to a helper called event(), whose output goes to Node's require().

scrypt, AES-GCM, and a write to disk

The routines in lib/cjs/utils/event.js derive a 256-bit key with scrypt and decrypt with AES-GCM; each blob carries a 16-byte salt, a 12-byte initialisation vector, a 16-byte authentication tag and the ciphertext as base64.

The helper writes the decrypted bytes to disk and returns a path that is then loaded, so the code runs with the process's own permissions. Because the file name loses its enc_ prefix before the write, a payload without that prefix overwrites its own encrypted source file. Three files under lib/cjs/utils/ hold base64 data instead of JavaScript: graph.js (20,918 bytes of ciphertext), fraction.js (9,084) and bignumber/type.js (1,179,416).

Two more packages, no trigger

A registry search turned up mathsbase and math-universe, which share the loader files, the trigger code and the solver changes across five versions. [email protected] appeared on 27 August 2026 and [email protected] on 17 September; npm still served the older [email protected], without the loader, as the default release.

The GitHub repositories listed by the two packages do not contain the added call in the commits SafeDep reviewed, so the public source does not explain the published build. The team tested 16,922 candidate passwords against the encrypted file name and 533 more against the five blobs without passing the authentication check, and its working hypothesis is that the packages store a payload for a later attack delivered by a separate package. None has been found, and the researchers say the code has not been shown to steal data or contact a server.

SSiTech

SiTech — AI-powered web development

We build fast, modern websites and bring AI into real business workflows. Have a project or a question? We'd love to help.