{"id":"MAL-2026-18185","revision":"6c3fa8ec689342e78361a621c1a617b5","records":[{"revision":"6c3fa8ec689342e78361a621c1a617b5","observedAt":"2026-10-24T13:17:17.793+00:00","statement":{"source":"osv","id":"MAL-2026-18185","aliases":[],"title":"Malicious code in log-rotate-testmetest (npm)","description":"\n---\n_-= Per source details. Do not edit below this line.=-_\n\n## Source: amazon-inspector (8608133ab1a2f106c095f84116cd25fa141208dbf81ea6fe2331e38a88551a4b)\nThe package ships a binding.gyp whose `sources` field uses GYP command-expansion (`<!(env node index.js...)`) with no native source files, causing npm's implicit `node-gyp rebuild` to execute index.js at install time. index.js is a Caesar+10 (ROT) obfuscated eval blob that, once decoded, AES-128-GCM-decrypts a hardcoded hex ciphertext and the sibling `data.bin`, brotli-decompresses the result, writes it to a mkdtemp'd temporary file, and spawns it under Bun (`Bun.spawn([execPath,'run',tmp])` / `spawn(getBunPath(),['run',tmp])`). package.json declares `bun` as a runtime dependency, deliberately routing execution through an alternate runtime rather than Node. The executed payload is fully opaque and attacker-controlled. The combination of a no-source binding.gyp used solely as a lifecycle trigger, multi-layer obfuscation (ROT + AES-GCM + brotli), and alternate-runtime dispatch has no legitimate native-build justification.\n","state":0,"publishedAt":"2026-10-22T06:11:42+00:00","modifiedAt":"2026-10-22T06:45:04.7710609+00:00","affected":[{"ecosystem":"npm","name":"log-rotate-testmetest","ranges":[],"versions":["1.0.1"],"rawVersionEvidence":null}],"metrics":[],"references":["https://www.npmjs.com/package/log-rotate-testmetest/v/1.0.1"],"sourceUrl":"https://osv.dev/vulnerability/MAL-2026-18185","license":"OSV · upstream source license applies","key":"osv:MAL-2026-18185","identifiers":["MAL-2026-18185"]},"retained":false,"historicalAffected":[]}],"coverage":[]}