{"id":"MAL-2026-18358","kind":"package","aliases":["MAL-2026-18358"],"related":[],"title":"Malicious code in @testsecuiitytestme/cache-helper (npm)","description":"@testsecuiitytestme/cache-helper is the only package of the npm account testsecuiitytestme. It was created on 2026-10-27 at 12:08 UTC with npm's staged-publish placeholder 0.0.0-stage, followed by 1.0.1 (12:28 UTC), 1.0.2 (15:33 UTC) and 1.0.3 (16:24 UTC); a 1.0.0 was removed before 14:21 UTC. It describes itself as \"Cache helper utilities\" and has no README, repository or source code. 1.0.3 was the latest version and still live at the time of this report.\n\nEach version runs a native addon at install time. 1.0.1 has postinstall: node -e \"try{require(process.platform==='win32'?'./addon_win.node':'./addon.node')}catch(e){}\". 1.0.2 and 1.0.3 depend on node-gyp-build and run it as postinstall, which loads the prebuilt addon shipped in prebuilds/linux-x64/node.napi.node or prebuilds/win32-x64/node.napi.node. 1.0.3 adds a binding.gyp with an empty sources list and an install script node-gyp rebuild, so the package looks like an ordinary native module; there is no C source in any version.\n\nThe addon (Linux ELF and Windows PE) is a loader. It checks for CI and sandbox environments (GITHUB_ACTIONS, GITLAB_CI, TRAVIS, CIRCLECI, JENKINS_URL, BUILDKITE, CODEBUILD_BUILD_ID and others, plus SANDBOX), containers (/proc/1/cgroup: docker, containerd, kubepods, podman), a debugger (TracerPid), memory and CPU count, then reads the sibling file .napi_cache, writes it to a hidden temp file and runs it in a detached process.\n\n.napi_cache is JavaScript encoded with a single-byte XOR (0x96). It exits under CI, decodes a second layer (repeating 32-byte XOR, then brotli), locates the Bun runtime or downloads bun 1.2.18 from the official oven-sh/bun GitHub releases, writes the decoded program to the temp directory and runs it detached with Bun. This loader shape matches the second wave of the Shai-Hulud npm worm.\n\nThe Bun program is obfuscated (javascript-obfuscator string table). Its strings show credential collection for npm, GitHub, GitLab, PyPI, RubyGems, JFrog, Docker Hub and GHCR, AWS, GCP, Azure, HashiCorp Vault and Kubernetes, plus .ssh, .git-credentials, .env files, browser login databases, the macOS keychain, 1Password and Bitwarden. They also show propagation: npm publishing with provenance, PyPI and RubyGems publishing, GitHub workflow and composite-action injection, GitLab CI template changes, and writes to AI assistant configuration (.claude/settings.json hooks, .cursor rules, .mcp.json, copilot-instructions.md, CLAUDE.md). The exfiltration endpoints sit behind a further string-encoding layer that was not decoded. Analysis was static only; nothing was executed.\n\nTarball sha256:\n1.0.1: a9c98033ac14fced8376bb8ba32bd92426b3729e16f5cd3852c5a97fc3503002\n1.0.2: 067a1350278fd1ae4fcc261eaca98964dd23a3c7940988ec43f95758480cf113\n1.0.3: 0e99f9a2eb7abcfe65278ca87a8e11dce25f39de2ff4bd77035e2bf01d26f0ed\n\nFile sha256:\n1.0.2 prebuilds/linux-x64/node.napi.node: 2547686f86fe6994bcf79558fcce441edc67aa734e255acf79870d5f47de7bbf\n1.0.2 prebuilds/win32-x64/node.napi.node: 620d2489e18b5a5f8840e96b90673d72db4c4c54d555ad66d179b3a5833e7763\n1.0.2 .napi_cache: 463dda65ebceeca6f5590dcdeae6c1d06ffadb2380a85b613deb2923af5557e7\n1.0.3 prebuilds/linux-x64/node.napi.node: 1fdd50b1bf66c4fd0e94f2be3db1f2f0fd77921136867022ad7e65e21220ad03\n1.0.3 prebuilds/win32-x64/node.napi.node: 5b7a0f53f2eca2dd4bf21e6df7d34e751b6cdf70b2f0a6f1f13edfb5caa9570b\n1.0.3 .napi_cache: c14dae9325f451c524cf858ecdae5fa68d2c645ee0981c6f42ef913c7ef34a57","summary":null,"severity":"critical","cvss":null,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"@testsecuiitytestme/cache-helper","fixed":[],"affected":"= 1.0.1; = 1.0.2; = 1.0.3","ecosystem":"npm"}],"ecosystems":["npm"],"tags":["malicious","package"],"not_affected_if":[],"how_to_check":null,"fix":null,"status":"open","published_at":"2026-10-27T16:30:00+00:00","first_seen_at":"2026-10-28T10:02:25+00:00","triaged_at":"2026-10-28T10:03:11+00:00","updated_at":"2026-10-28T10:10:10+00:00","category":"package","confidence":null,"triage":null,"analyst_status":null,"analyst_note":null,"search":"'-10':30C '-18358':8A,11A '-2026':7A,10A '-27':31C '/addon.node':116C '/addon_win.node':115C '/bun':284C '/proc/1/cgroup':211C '0.0.0':43C '067a1350278fd1ae4fcc261eaca98964dd23a3c7940988ec43f95758480cf113':427C '08':34C '0e99':429C '0x96':255C '1.0.0':61C '1.0.1':47C,106C,424C '1.0.2':51C,119C,426C,433C,436C,439C '1.0.3':56C,83C,121C,143C,428C,443C,446C,449C '1.2.18':277C '12':33C,48C '14':65C '15':52C '16':57C '1fdd50b1bf66c4fd0e94f2be3db1f2f0fd77921136867022ad7e65e21220ad03':445C '1password':361C '2026':29C '21':66C '24':58C '2547686f86fe6994bcf79558fcce441edc67aa734e255acf79870d5f47de7bbf':435C '28':49C '32':265C '33':53C '463dda65ebceeca6f5590dcdeae6c1d06ffadb2380a85b613deb2923af5557e7':442C '5b7a0f53f2eca2dd4bf21e6df7d34e751b6cdf70b2f0a6f1f13edfb5caa9570b':448C '620d2489e18b5a5f8840e96b90673d72db4c4c54d555ad66d179b3a5833e7763':438C 'a9c98033ac14fced8376bb8ba32bd92426b3729e16f5cd3852c5a97fc3503002':425C 'account':23C 'action':195C,381C 'add':144C 'addon':102C,137C,178C 'ai':390C 'also':365C 'analysi':415C 'assist':391C 'aw':341C 'azur':343C 'behind':404C 'binding.gyp':146C 'bitwarden':363C 'brot':269C 'browser':355C 'build':127C,204C 'buildkit':202C 'bun':272C,276C,300C,316C 'byte':253C,266C 'c':172C 'c14dae9325f451c524cf858ecdae5fa68d2c645ee0981c6f42ef913c7ef34a57':452C 'cach':72C,229C,245C,441C,451C 'catch':117C 'chang':386C 'check':188C 'ci':190C,197C,259C,384C 'circleci':199C 'claude.md':399C 'claude/settings.json':393C 'code':2A,82C 'codebuild':203C 'collect':329C 'composit':380C 'composite-act':379C 'configur':392C 'contain':210C 'containerd':213C 'copilot-instructions.md':398C 'count':222C 'cpu':221C 'creat':27C 'credenti':328C,352C 'cursor':395C 'databas':357C 'debugg':217C 'decod':260C,289C,414C 'depend':122C 'describ':69C 'detach':242C,298C 'directori':294C 'docker':212C,337C 'download':275C 'e':110C,118C 'elf':180C 'empti':149C 'encod':248C,409C 'endpoint':402C 'env':353C 'environ':193C 'execut':421C 'exfiltr':401C 'exit':257C 'f9a2eb7abcfe65278ca87a8e11dce25f39de2ff4bd77035e2bf01d26f0ed':430C 'file':227C,236C,354C,431C 'follow':45C 'gcp':342C 'ghcr':340C 'git':351C 'git-credenti':350C 'github':194C,285C,332C,376C 'gitlab':196C,333C,383C 'gyp':126C,158C 'hashicorp':344C 'helper':73C 'hidden':234C 'hook':394C 'hub':338C 'hulud':312C 'id':205C 'inject':382C 'instal':104C,154C 'javascript':247C,321C 'javascript-obfusc':320C 'jenkin':200C 'jfrog':336C 'keychain':360C 'kubepod':214C 'kubernet':347C 'latest':86C 'layer':263C,410C 'like':164C 'linux':179C 'list':151C 'live':90C 'load':134C 'loader':186C,302C 'locat':270C 'login':356C 'look':163C 'maco':359C 'mal':6A,9A 'malici':1A,13B 'match':304C 'mcp.json':397C 'memori':219C 'modul':168C 'napi':228C,244C,440C,450C 'nativ':101C,167C 'node':109C,125C,157C 'node-gyp':156C 'node-gyp-build':124C 'noth':419C 'npm':5A,22C,37C,313C,331C,368C 'obfusc':319C,322C 'offici':280C 'ordinari':166C 'other':207C 'oven':282C 'oven-sh':281C 'packag':14B,19C,162C 'pe':183C 'placehold':42C 'plus':208C,348C 'podman':215C 'postinstal':108C,132C 'prebuilds/linux-x64/node.napi.node':140C,434C,444C 'prebuilds/win32-x64/node.napi.node':142C,437C,447C 'prebuilt':136C 'process':243C 'process.platform':113C 'program':290C,317C 'propag':367C 'proven':371C 'publish':41C,369C,375C 'pypi':334C,372C 'read':224C 'readm':78C 'rebuild':159C 'releas':286C 'remov':63C 'repeat':264C 'report':96C 'repositori':79C 'requir':112C 'rubygem':335C,374C 'rule':396C 'run':99C,129C,238C,296C 'runtim':273C 'sandbox':192C,209C 'script':155C 'second':262C,306C 'sh':283C 'sha256':423C,432C 'shai':311C 'shai-hulud':310C 'shape':303C 'ship':138C 'show':327C,366C 'sibl':226C 'singl':252C 'single-byt':251C 'sit':403C 'sourc':81C,150C,173C 'ssh':349C 'stage':40C,44C 'staged-publish':39C 'static':417C 'still':89C 'string':323C,326C,408C 'string-encod':407C 'tabl':324C 'tarbal':422C 'temp':235C,293C 'templat':385C 'testsecuiitytestm':24C 'testsecuiitytestme/cache-helper':4A,12A,15C 'time':93C,105C 'tracerpid':218C 'travi':198C 'tri':111C 'url':201C 'utc':35C,50C,54C,59C,67C 'util':74C 'vault':345C 'version':87C,98C,176C 'wave':307C 'win32':114C 'window':182C 'workflow':377C 'worm':314C 'write':230C,287C,388C 'xor':254C,267C","nicknames":[],"mitigations":[],"who_affected":null,"tier":"B","verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-27T16:30:00+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"osv-malicious","external_id":"MAL-2026-18358","url":"https://osv.dev/vulnerability/MAL-2026-18358","severity":"critical","published_at":"2026-10-27T16:30:00+00:00","modified_at":"2026-10-28T09:30:16+00:00","first_seen_at":"2026-10-28T10:02:25+00:00","fetched_at":"2026-10-28T10:02:25+00:00","note":null}],"documents":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}