# strutil-core: a RubyGems worm writes itself into AI agent configs

> strutil-core is a malicious RubyGems package whose install-time payload steals credentials and plants itself in AI coding agent config files.

- **Severity:** Medium: Real and reproducible, but needs unusual setup, user help or a narrow audience. Plan a fix.
- **Category:** Supply chain
- **Published by:** Socket
- **Disclosed:** 2026-11-06
- **Affects:** RubyGems, Claude Code, Cursor, OpenAI Codex, Aider, Visual Studio Code
- **Research by:** Kush Pandya, Socket Threat Research Team
- **Primary source:** https://socket.dev/blog/shai-hulud-descendant-malicious-ruby-gem
- **Page:** https://theinjection.dev/items/socket-strutil-core-ruby-gem-worm/

strutil-core 1.0.1 is a malicious RubyGems package that steals credentials during install and edits AI coding tool config files so agents run it again. Socket reports RubyGems removed both published versions.

## What happened

Socket published an analysis of the RubyGems package strutil-core on November 6, 2026, whose gemspec advertises string manipulation helpers. The account jamnajiea published a clean 1.0.0 on November 1, 2026 and pushed the malicious 1.0.1 less than two hours later. Socket identifies the payload as a new build of the testmetest worm, part of the Miasma family that grew from the public Shai-Hulud toolkit.

## How it works

A native extension script runs during gem install or bundle install, downloads the Bun JavaScript runtime and executes a 5.48 MB bundle, so no application needs to require the gem. The payload collects cloud, CI, package registry, SSH, AI coding tool and wallet credentials and sends them to paleasbest[.]top, with GitHub and GitLab fallbacks. It then searches the home directory for writable settings.json, config.json, mcp.json and .aider.conf.yml files, adds an MCP server named workspace-tools that runs the payload with node, and adds SessionStart hooks. With stolen Git credentials it commits agent config files into repositories, including a generated AGENTS.md that tells coding agents to run a setup script before their first command.

## Who is affected

Only strutil-core 1.0.1 carries the payload, and Socket cites Bitbison for RubyGems removing both versions about five hours after the malicious release. Socket says it has confirmed no victims and does not know how many systems installed 1.0.1; the figures in the table below are download counts, which Socket says are not victim counts and likely came from mirrors and scanners. Repositories that received the worm's committed config files can run it again when a coding agent or editor opens them, depending on each tool's workspace trust setting.

## What to do

Search developer machines and repositories for the artifacts Socket lists: an MCP server named workspace-tools, SessionStart hooks in agent config files, and generated AGENTS.md, CLAUDE.md or .vscode/tasks.json entries that run a setup script. Contain an affected host and preserve its data before revoking credentials, because Socket reports a monitor that wipes the user's home directory once a stolen GitHub token stops working. Removing the gem is not enough, since the payload writes outside the gem directory.

## Quick facts

- **Affected:** strutil-core 1.0.1 on RubyGems
- **Timeline:** Clean 1.0.0 published 2026-11-01, malicious 1.0.1 under two hours later
- **Status:** Both versions removed from RubyGems, per Socket
- **Downloads:** 89 recorded across both versions, 0 for 1.0.1
- **Exfiltration:** paleasbest[.]top, with GitHub and GitLab fallbacks
- **Persistence:** Python backdoor pkg-runtime, driven by signed GitHub commit messages
- **Wiper trigger:** net-health-checker deletes the home directory on HTTP 401 or 403 from a stolen GitHub token
- **Found by:** Socket Threat Research Team

## Questions

### Was anyone compromised by strutil-core 1.0.1?

Socket reports no confirmed victims of strutil-core 1.0.1 and says it does not know how many systems installed the malicious version. A public RubyGems metadata tracker recorded 89 total downloads across both versions and 0 for 1.0.1, which Socket attributes to mirrors and automated scanners rather than real installs. Download counts are not victim counts.

### Does uninstalling the strutil-core gem remove the infection?

Uninstalling strutil-core does not undo an infection, because the payload writes outside the gem directory. Socket describes a Python backdoor named pkg-runtime that takes commands from signed GitHub commit messages, plus edits to AI coding tool configuration files in the home directory and in reachable repositories. Cleanup means finding those artifacts and rotating every credential the machine held.

### Which AI coding tools does strutil-core target?

Socket names Claude, Cursor, Gemini, Codex, Aider and Visual Studio Code among the tools whose configuration files the payload edits. The worm looks for writable settings.json, config.json, mcp.json and .aider.conf.yml files, registers an MCP server called workspace-tools, and commits files such as CLAUDE.md, AGENTS.md and .vscode/tasks.json into repositories it can reach with stolen Git credentials.

### Why does revoking a stolen GitHub token trigger the strutil-core wiper?

Socket describes a monitor component named net-health-checker that watches a stolen GitHub token. Once that token starts returning HTTP 401 or 403, the monitor deletes the user's home directory, so ordinary revocation is what sets off the destructive step. Responders should therefore isolate the host and copy off anything they need before rotating credentials.

## Sources

1. [Socket Analysis](https://socket.dev/blog/shai-hulud-descendant-malicious-ruby-gem)
2. [OpenSSF Report](https://github.com/ossf/malicious-packages/pull/1701)
