// hackerlogs
login+ register
Supply ChainLLM AppSecThreat BriefHigh

GitHub Had the Math. npm Had the Encrypted Loader.

Hacker News: SafeDep found an npm mathjs clone whose solver unlocks a RAT. JFrog cracked the trigger. The GitHub tree was clean. The tarball was not.

The short answer

SafeDep found a remote-access implant in npm mathjs clones. The loader stays dark until a caller hits the solver with matrix data as the password. JFrog recovered that trigger on 21 September. Reviewed GitHub trees lack the extra call. The npm tarball does. npm later pulled the packages. Download counts were not a user base.

Key takeaways

  • Hacker News put SafeDep on the board today. JFrog published the trigger on 21 September. The implant waits in lusolve after the honest answer is already computed.
  • No install hook. A normal import does not wake it. The password is not in the package. The caller's own matrix data has to produce it.
  • Reviewed GitHub commits for mathsbase and math-universe lack the extra solver call. The npm build has it. Source is not the artifact.
  • Three names: mathmain, mathsbase, math-universe. npm download totals in the hundreds of thousands do not match dependents. JFrog calls the traffic a farm.
  • Hunt the tarball hashes and a LICENSE line that does not belong. A pulled package is not a hunt of every lockfile that ever resolved it.

Hacker News put SafeDep's mathmain post on the front page today. US X Trends were football. Google still had yesterday's Codex escapes. This is the other ticket: an npm math clone whose solver waits for one piece of matrix data, then unlocks a remote-access implant.

High Encrypted RAT in a mathjs copy. High because the GitHub tree was not the artifact, not because a named victim posted a dump.

mathmain encrypted loader: a solver that stays dark until the right matrix data lands, a clean GitHub tree against a dirty npm tarball, and the operator work of hunting lockfiles after npm pulled the name.

What SafeDep and JFrog actually published.#

SafeDep started on 17 September with mathmain, a renamed mathjs tree plus obfuscation. One extra call sat at the end of the linear solver, after the honest result already existed. That call handed matrix data to a helper that treated the JSON form of the lower factor as a password, then tried to decrypt and load staged files.

JFrog published the trigger on 21 September. SafeDep reproduced it the same day. The implant does not ship the password. The caller's own numerical work has to produce it. Any other input fails the authentication check. The solver still returns the correct answer. The extra call's return value is thrown away.

The same loader family landed in mathsbase and math-universe. SafeDep hashed five tarballs. On 17 September, npm's default mathmain release was a version without this loader. Checking only latest would have missed it.

We are not reprinting the decrypt steps or the exact matrix as a working recipe. The operator fact is enough. A math import can hide a staged implant that only a later call unlocks.

Hacker News commenters saw npm's removal notice. Treat that as the registry clock, not the impact clock. Same shape as the TanStack token: the package can be gone while a lockfile still points at the tarball.

Why the GitHub tree is the wrong receipt.#

JFrog's download picture does not match dependents. mathsbase showed millions of downloads days after publish, and no package depending on it. SafeDep's week of counts for the three names sat in the hundreds of thousands, then npm reported a zero-download day for the whole registry. Neither number is an install base. JFrog describes a farm of GitHub Actions workers manufacturing traffic.

The implant, once unlocked, is a small remote-access stack. SafeDep's static read: host inventory, a testnet contract as a drop, Slack and Telegram as side channels, later stages written to disk and started. JFrog adds an infection marker hidden in LICENSE, a detached respawn, and a wallet that only unwraps on a host that both installed the package and hit the trigger. Very Serious Systems independently decrypted a stage and found a broken bootstrap on one copy. Do not file every host as fully tasked. File the class: encrypted payload, runtime key, command channel that looks like ordinary Web3.

  1. mathmain 1.0.0 publishes. SafeDep finds no matching loader.
  2. mathmain 1.0.1 publishes with the loader and encrypted files.
  3. mathsbase and math-universe versions land with the same family.
  4. SafeDep starts the review. Default mathmain on npm that day is a version without this loader.
  5. SafeDep publishes the encrypted-loader question.
  6. JFrog recovers the trigger and maps the campaign. SafeDep reproduces and reads the payload.
  7. Hacker News fronts the SafeDep post. npm's removal notice is already in the thread.

What this is not.#

It is not TanStack and not Plugin4Shell. Those were a trusted publisher and a pin that did not verify. This is a clone that waited for a solver call.

It is not a drive-by install worm. SafeDep's path needs the extra call and the right matrix data. That is why public searches found no caller. Private code is still in scope.

It is also not a reason to trust latest. The clean default and the dirty version sat on the same name.

What to do.#

If you install npm math helpers, or your agents do:

  1. Read SafeDep and JFrog as the scope. Three names. Loader in the tarball, not in the reviewed GitHub tree. Trigger after an honest solve. npm pulled the malicious code.
  2. Search lockfiles and images for mathmain, mathsbase, and math-universe. Match SafeDep's archive hashes, not the live page.
  3. Compare any mathjs clone's GitHub tree to the tarball you actually installed. The extra solver call is the tell.
  4. Hunt the LICENSE marker and decrypted stage files JFrog and SafeDep named. A yanked package can still have written them.
  5. Block the family at install. Do not use download counts as popularity. Do not let an agent add a math helper because the README looks like mathjs.

The package clock is a removal notice. The impact clock is every cache that still has the tarball. GitHub was the brochure. npm was the implant.

Frequently asked

Is this the TanStack npm worm?

No. TanStack was a six-minute publish window and a stolen CI token that later read private git. mathmain is a mathjs clone whose npm tarball hid an encrypted implant behind a solver call. Same lesson, different clock: the registry can look quiet while the artifact is already wrong.

Does installing the package run the implant?

Not on the path SafeDep reviewed. There is no install hook, and a normal import does not reach the extra solver call. The loader waits for matrix data that produces the password. Wrong data fails the authentication check and writes nothing. That is a filter, not a comfort. Private callers and removed projects are outside the public search.

Are the packages still on npm?

Hacker News commenters saw a removal notice: the npm security team pulled malicious code. Do not treat the live page as the inventory. Check lockfiles, caches, and images for the versions SafeDep hashed. A yanked name can still be on a runner.

What should a team change tonight?

Search for mathmain, mathsbase, and math-universe. Compare GitHub to the tarball. Hunt the extra solver call and the LICENSE marker JFrog described. Block the family at install. Do not trust download counts or a clean default latest when another version held the loader.

Sources

  1. lusolve() and you shall receive Very Serious Systems · 2026-09-21

Related