MemTensor npm and PyPI packages backdoored with self-propagating Go worm sckit after GitHub Actions release token theft
On September 23, 2026, an attacker published malicious versions of @memtensor/memos-cloud-openclaw-plugin (npm, versions 0.1.21, 0.1.23 and 0.1.25 per the article) and the MemoryOS Python library (PyPI, 2.0.34). Both carry the same Go implant, sckit, which harvests credentials from the home directory, exfiltrates them to servers under skyleen[.]fr, and contains code to copy itself into other repositories and packages reachable with the stolen credentials. The attacker obtained the publish tokens by pushing commits to MemTensor's GitHub Actions release pipelines that leaked the npm and PyPI tokens before publishing. SafeDep found the incident after an issue on the plugin repository reported versions that matched no commit. The initial push access as the Memtensor-AI account is unexplained; a stolen token is the likely cause but is unconfirmed.
Detalhes técnicos
- npm token theft: commits on short-lived
sc/release-*branches (e.g. 9b97ec6) modifiedvalidate-release-confirmation.mjsto writeBASH_ENVinto$GITHUB_ENV, sosckit-publish-bridge.shran before the real publish step. It passedNPM_TOKENto the sckit binary viacollectStageZero(), deleted itself and exited 1, so the run published nothing. The branch was pushed five times between 00:48 and 02:03 UTC and deleted after each push. - PyPI token theft: tag v2.0.34 initially pointed to unsigned commit b52958f (not on main), which added six sckit binaries and a malicious Poetry build backend (
sckit_poetry_build). It used the sameBASH_ENVtrick to run_pypi_bridge.shinside the pypa publish action and sendINPUT_PASSWORDto a skyleen[.]fr endpoint through_initial_ci_delivery.py. About two hours later commit 41bf5c7 ("chore: allow native PyPI upload [skip ci]") removed theregister()call, the tag was recreated and MemTensor's own workflow published the malicious package with the real token. SafeDep reads the deleted tag v2.0.34-capture-1 as a token-capture run. - Execution: no install hook is used, so
--ignore-scriptsdoes not help. The npm plugin launches the binary on OpenClaw gateway start and on each memory recall, sending the user prompt asSCKIT_EVENT_TEXT. MemoryOS launches it fromconfigure_logging(). Version 0.1.25 bundlesca-roots.pemand setsSSL_CERT_FILEon hosts without a system certificate store. The wheel grew from 951 KB to 19 MB. - Implant: Go go1.27.1, module
supplychain.local/campaign/cmd/implant. It collects.npmrc,.pypirc,.git-credentials,.netrc, SSH keys,.vault-token, MSAL caches and secret-like environment variables, and matches token formats for AWS, GitHub, GitLab, npm, PyPI, Hugging Face, Vault, Slack, Stripe and SendGrid. Worm functions (findRepositories,PrepareRemoteRepository,recursivePublish) write loaders into victim repos, including aruntime-update.ymlGitHub Actions workflow. It has geo and TLS-fingerprint filtering fields (geo_iso,deny_iso,ja4_deny), a CBOR/X25519/XChaCha20-Poly1305 C2 protocol with signed modules, and self-delete routines. Campaign IDs arecloud-openclaw-semi-nuclearandmemos-semi-nuclear;not_afterdecodes to roughly October 22-23, 2026. - The article suggests, as an unconfirmed inference, that a language model helped write the tooling. Affected-package lists may grow because the worm spreads.
Remediação
- Remove the affected packages and pin clean versions: 0.1.20 for the plugin and 2.0.33 for MemoryOS.
- Kill any
sckitprocess and delete$HOME/.openclaw/.cache/runtimeand$HOME/.memos/.cache/runtime. - Rotate every credential reachable from
$HOMEand the process environment (npm, PyPI, GitHub, GitLab, SSH, cloud CLI tokens,.envsecrets). - Check repositories you can push to for an unexpected
runtime-update.ymlworkflow or a.sckit/directory. - Maintainers: do not let publish jobs trust scripts from the commit being built, use trusted publishing, protected tags, required reviewers on the release environment, and provenance attestations.
Linha do tempo
-
MemTensor npm and PyPI packages backdoored with self-propagating Go worm sckit after GitHub Actions release token theft
ler a análise desta fonte ocultar
On September 23, 2026, an attacker published malicious versions of @memtensor/memos-cloud-openclaw-plugin (npm, versions 0.1.21, 0.1.23 and 0.1.25 per the article) and the MemoryOS Python library (PyPI, 2.0.34). Both carry the same Go implant, sckit, which harvests credentials from the home directory, exfiltrates them to servers under skyleen[.]fr, and contains code to copy itself into other repositories and packages reachable with the stolen credentials. The attacker obtained the publish tokens by pushing commits to MemTensor's GitHub Actions release pipelines that leaked the npm and PyPI tokens before publishing. SafeDep found the incident after an issue on the plugin repository reported versions that matched no commit. The initial push access as the Memtensor-AI account is unexplained; a stolen token is the likely cause but is unconfirmed.
Technical Details
- npm token theft: commits on short-lived
sc/release-*branches (e.g. 9b97ec6) modifiedvalidate-release-confirmation.mjsto writeBASH_ENVinto$GITHUB_ENV, sosckit-publish-bridge.shran before the real publish step. It passedNPM_TOKENto the sckit binary viacollectStageZero(), deleted itself and exited 1, so the run published nothing. The branch was pushed five times between 00:48 and 02:03 UTC and deleted after each push. - PyPI token theft: tag v2.0.34 initially pointed to unsigned commit b52958f (not on main), which added six sckit binaries and a malicious Poetry build backend (
sckit_poetry_build). It used the sameBASH_ENVtrick to run_pypi_bridge.shinside the pypa publish action and sendINPUT_PASSWORDto a skyleen[.]fr endpoint through_initial_ci_delivery.py. About two hours later commit 41bf5c7 ("chore: allow native PyPI upload [skip ci]") removed theregister()call, the tag was recreated and MemTensor's own workflow published the malicious package with the real token. SafeDep reads the deleted tag v2.0.34-capture-1 as a token-capture run. - Execution: no install hook is used, so
--ignore-scriptsdoes not help. The npm plugin launches the binary on OpenClaw gateway start and on each memory recall, sending the user prompt asSCKIT_EVENT_TEXT. MemoryOS launches it fromconfigure_logging(). Version 0.1.25 bundlesca-roots.pemand setsSSL_CERT_FILEon hosts without a system certificate store. The wheel grew from 951 KB to 19 MB. - Implant: Go go1.27.1, module
supplychain.local/campaign/cmd/implant. It collects.npmrc,.pypirc,.git-credentials,.netrc, SSH keys,.vault-token, MSAL caches and secret-like environment variables, and matches token formats for AWS, GitHub, GitLab, npm, PyPI, Hugging Face, Vault, Slack, Stripe and SendGrid. Worm functions (findRepositories,PrepareRemoteRepository,recursivePublish) write loaders into victim repos, including aruntime-update.ymlGitHub Actions workflow. It has geo and TLS-fingerprint filtering fields (geo_iso,deny_iso,ja4_deny), a CBOR/X25519/XChaCha20-Poly1305 C2 protocol with signed modules, and self-delete routines. Campaign IDs arecloud-openclaw-semi-nuclearandmemos-semi-nuclear;not_afterdecodes to roughly October 22-23, 2026. - The article suggests, as an unconfirmed inference, that a language model helped write the tooling. Affected-package lists may grow because the worm spreads.
Remediation
- Remove the affected packages and pin clean versions: 0.1.20 for the plugin and 2.0.33 for MemoryOS.
- Kill any
sckitprocess and delete$HOME/.openclaw/.cache/runtimeand$HOME/.memos/.cache/runtime. - Rotate every credential reachable from
$HOMEand the process environment (npm, PyPI, GitHub, GitLab, SSH, cloud CLI tokens,.envsecrets). - Check repositories you can push to for an unexpected
runtime-update.ymlworkflow or a.sckit/directory. - Maintainers: do not let publish jobs trust scripts from the commit being built, use trusted publishing, protected tags, required reviewers on the release environment, and provenance attestations.
- npm token theft: commits on short-lived