Skip to content

Published yesterday Security 7 min read

GitLab and npm attacks that skip credential theft both start with a repository the attacker creates

GitLab patched CVE-2026-97229, a CVSS 10.0 code-execution flaw, on October 12. Rapid7 found it needs an attacker-planted CI/CD file, while Bloom Security found 1,500+ npm packages open to takeover through freed GitHub names.

Send a correction

Widely confirmed7 publishersOperator

Not a builder's beat, but builders have a standing stake in it.

Generated illustration
npm packages open to takeover are widely downloaded Bloom Security's count of npm packages exposed to takeover through freed GitHub repository names, and those packages' downloads.

Bloom Security counted more than 1,500 npm packages exposed to takeover. Together the exposed packages have more than 10 million downloads in total and more than a million downloads a month.

npm packages open to takeover are widely downloaded
FigureValueNoteClaim
npm packages Bloom counted as exposed, over1,500 packages22
Total downloads, over10,000,000 downloads22
Downloads a month, over1,000,000 downloads22

What happened

  • On October 12, 2026 GitLab released versions 19.4.2, 19.3.5 and 19.2.8 for Community Edition and Enterprise Edition. CVE-2026-97229 affects all versions from 19.2 before 19.2.8, 19.3 before 19.3.5, and 19.4 before 19.4.2.
  • GitLab rates CVE-2026-97229, an integer overflow in the CI/CD Regular Expression Compiler, at CVSS 10.0 with the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H, which sets privileges required and user interaction to none.
  • GitLab's advisory says it remediated an issue that, 'under certain conditions', could have allowed an unauthenticated user to execute arbitrary code on the GitLab server via a specially crafted regular expression in a CI/CD configuration, due to insufficient regular expression validation.
  • Rapid7 said that although the vendor-supplied CVSS score indicates fully unauthenticated exploitation, in reproducing the exploit an attacker must have a mechanism to plant a malicious CI/CD configuration to a repository before triggering the vulnerability. On GitLab instances where new users can self register and create projects, this constraint is removed.
  • Rapid7's testing found an attacker must commit a malicious .gitlab-ci.yml and a repository path containing UTF-8 characters to a branch in a public project. An ordinary account can satisfy this prerequisite by creating a public project on a self-managed GitLab instance where that functionality is permitted.

Why it matters

Where "no login" stops on the GitLab side

GitLab scores CVE-2026-97229 at CVSS 10.0, with a vector that sets privileges required and user interaction to none [2]. The advisory says that "under certain conditions" an unauthenticated user could run arbitrary code on the GitLab server through a crafted regular expression in a CI/CD configuration [3]. Shane Barney, chief information security officer at Keeper Security, took the vector at face value. He said exploitation requires no authentication and no user interaction [18].

Rapid7 reproduced the exploit and found a step the score leaves out. The attacker needs a way to plant a malicious CI/CD configuration in a repository before triggering the bug [4]. In Rapid7's test that meant committing a .gitlab-ci.yml file and a repository path containing UTF-8 characters to a branch in a public project [5]. An ordinary account can do that by creating a public project, where the instance permits it [5]. On instances where new users can self-register and create projects, Rapid7 said, the constraint is removed [4]. Orca states the open condition more broadly: no authentication is needed where an instance allows public project creation or user self-registration [13].

In our view, exposure is set by each instance's sign-up and project policy. A server with open registration lets anyone satisfy the prerequisite [4]. A closed one needs an attacker who already holds an account that can create or write to a public project [5]. "No login" is accurate for the first case and an overstatement for the second.

What the exploit does once it runs

The flaw is an ordering problem. The crafted expression first compiles in a compact US-ASCII form and passes GitLab's regular expression validation [6]. When it is evaluated against a specially formed, valid UTF-8 repository path, Ruby's Onigmo engine recompiles it for the new encoding after those checks have completed [6]. An integer overflow in the program-size calculation then generates invalid instructions, and the resulting loss of control-flow integrity lets attacker-controlled Onigmo VM operations run an operating system command as the GitLab git user [6].

Rapid7 validated the chain against the official GitLab 19.4.1 CE Linux amd64 image with address space layout randomization enabled [7]. The same input did not execute against the patched 19.4.2 image [7].

Rapid7's description of the exploit reaches a command running as the git user [6]. The step from there to secrets comes from other analysts. Roman Sannikov of iCounter said a self-managed GitLab server holds source code, build pipelines and usually the credentials those pipelines use to reach cloud accounts, package registries and production [15]. A second fix in the same release touches the same material. CVE-2026-14814, rated CVSS 8.2, let a user poison cached responses for raw repository files, so targeted users' pipelines would run crafted content and could expose protected environment variables [19].

No source reports secrets taken from a live instance. Rapid7 reported no confirmed exploitation in the wild as of its October 13 post [8].

The clock and the cost

GitLab shipped 19.4.2, 19.3.5 and 19.2.8 on October 12 [1]. Rapid7 published its reproduction the next day [8]. GitLab's previous maximum-severity flaw, CVE-2026-85706, drew in-the-wild probing within hours of disclosure and was later added to CISA's KEV catalog, according to Orca [10]. Sannikov said "Teams should assume the window between disclosure and exploitation is days, not weeks," and pointed to scanning that began shortly after disclosure of that earlier flaw [16].

GitLab's issue tracker publishes details of security fixes 90 days after the release that patched them [20]. For this release that date is January 10, 2027 [40]. Rapid7 said its root-cause and exploit-chain detail will come in a separate technical analysis [9].

The fix is the upgrade. The affected range is every version from 19.2 before 19.2.8, 19.3 before 19.3.5 and 19.4 before 19.4.2 [1]. GitLab.com is already patched and GitLab Dedicated customers need take no action [11]. For them this flaw does not matter.

Self-managed teams who cannot upgrade today have partial options. Orca says GitLab has published no workaround and recommends disabling user self-registration where it is not needed [14]. Rapid7 lists restricting anonymous access to public projects and keeping untrusted users from creating or writing to them, and says those controls cover only the demonstrated delivery path and do not fix the compiler [12]. After patching, Sannikov advised looking at what a compromised instance could have reached, rotating CI/CD secrets and tokens, and reviewing runner and pipeline activity since disclosure [17].

The npm side: trusting a name

Bloom Security found that npm's Trusted Publishing let an attacker push new versions of someone else's package without stealing a credential [21]. The attacker only had to register a GitHub repository name that the maintainer had left behind [21]. Bloom counted more than 1,500 exposed packages with more than 10 million downloads in total and more than a million a month [22].

The cause is what npm recorded when a maintainer set up a trusted publisher. It stored the repository by its owner/repo name, the slug. GitHub puts permanent numeric IDs for the repository and owner in the identity token it issues, and npm did not check them [23]. Golan Myers, a security researcher at Bloom, described it this way: "It is like a lock that checks the address on the door rather than who owns the house: when the owner moves out, whoever moves in gets the key." [25]

Two conditions limit the attack. The victim's trusted publisher has to point at a slug an attacker can claim, and the repository must never have been used to publish a version of the package [24]. Given both, the attacker creates a repository at the freed slug, which gets a fresh numeric ID, then triggers a publish workflow that mints a token carrying the reclaimed slug and the new ID. npm matches the slug and issues a time-limited publish credential for a package the attacker does not own [24]. Bloom ran this end to end on a package and repositories its researchers controlled [38].

GitHub already retires the names of repositories with more than 100 clones in the week before an owner account is renamed or deleted [27]. That protects some packages. "We took this into account. Everything we considered vulnerable was pertaining to claimable slugs," said Myers [27].

A malicious release can carry a postinstall hook, and its code can run during installation on developer machines or continuous integration systems [33]. The release also carries a valid provenance attestation, a signed build record, and it names the attacker's repository [26]. A consumer who checks only that an attestation exists would find one. Bloom advises checking that the attestation names the repository the project is supposed to come from, and it is not publishing the affected package names, so there is no list to check against [36].

Bloom argues that AI coding agents widen the reach. From telemetry across dozens of organizations, it estimates that agents on a typical endpoint install about 70 packages a month and close to 350 on developer machines, excluding dependencies, usually without a review of the package or its maintainer [37]. Both figures are Bloom's own.

How fast GitHub moved, and what it left open

Bloom reported the flaw through GitHub's HackerOne bug bounty program on June 6, and GitHub validated it on June 9 [28]. Bloom says GitHub's last reply came on July 8 and that six follow-ups, including a mediation request to HackerOne, went unanswered [29]. GitHub announced its change on October 2 [30]. From report to announcement is 118 days [39].

The change expires unvalidated trusted publishing configurations 48 hours after creation. A configuration becomes exempt after its first successful publish, and changing the repository or project identity requires a new trust relationship with a fresh 48-hour window [31]. That targets the exposed population, since the slug swap only works against a binding that has never published [24]. GitHub's statement does not say whether configurations that published before the change were bound retroactively [30].

Maintainers can run npm trust list and confirm each listed repository still resolves to one they control. They should delete and re-create any binding that points at a renamed or transferred repository, and remove a binding before deleting a repository [35].

Where the two meet

Both attacks skip credential theft, and both begin when the attacker creates a repository: a public project on a GitLab instance, or a repository at a freed name on GitHub [5][24]. Both end in the build pipeline. On the GitLab side that is the server that, per Sannikov, holds pipeline credentials [15]. On the npm side it is the developer machines and CI systems that run a malicious postinstall hook [33].

There is also a direct link. Bloom says npm's GitLab trusted publishing integration has the same weakness [34]. GitHub's description of the fix refers to repository or project identity [31], and the sources do not say whether GitLab-side bindings were changed.

The two differ in what is known. GitLab's flaw has a patch, a lab reproduction and no confirmed exploitation as of October 13 [8]. The npm flaw has a fix and a controlled demonstration, and Myers said it is unknown whether anyone exploited it in the wild [32].

What to watch

  • Rapid7's separate technical analysis of CVE-2026-97229, and the first confirmed exploitation; GitLab's previous 10.0 flaw drew probes within hours of disclosure and later reached CISA's KEV catalog.
  • Whether GitHub says npm configurations that published before the change were bound retroactively, and whether the GitLab trusted publishing integration gets the same fix.
  • Any report that SlugFest was used against a real package; Bloom's researcher said it is unknown whether anyone exploited it.

Claim ledger

Ranked by verification strength, evidence, and original report placement.

  1. [1]

    On October 12, 2026 GitLab released versions 19.4.2, 19.3.5 and 19.2.8 for Community Edition and Enterprise Edition. CVE-2026-97229 affects all versions from 19.2 before 19.2.8, 19.3 before 19.3.5, and 19.4 before 19.4.2.

    Reported Source: GitLab critical patch release notice, October 12, 2026View cited source
  2. [2]

    GitLab rates CVE-2026-97229, an integer overflow in the CI/CD Regular Expression Compiler, at CVSS 10.0 with the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H, which sets privileges required and user interaction to none.

    Reported Source: GitLab patch release noticeView cited source
  3. [3]

    GitLab's advisory says it remediated an issue that, 'under certain conditions', could have allowed an unauthenticated user to execute arbitrary code on the GitLab server via a specially crafted regular expression in a CI/CD configuration, due to insufficient regular expression validation.

    Reported Source: GitLab advisoryView cited source
  4. [4]

    Rapid7 said that although the vendor-supplied CVSS score indicates fully unauthenticated exploitation, in reproducing the exploit an attacker must have a mechanism to plant a malicious CI/CD configuration to a repository before triggering the vulnerability. On GitLab instances where new users can self register and create projects, this constraint is removed.

    Reported Source: Rapid7 blog, October 13, 2026View cited source
  5. [5]

    Rapid7's testing found an attacker must commit a malicious .gitlab-ci.yml and a repository path containing UTF-8 characters to a branch in a public project. An ordinary account can satisfy this prerequisite by creating a public project on a self-managed GitLab instance where that functionality is permitted.

    Reported Source: Rapid7 blogView cited source
  6. [6]

    The crafted regular expression initially compiles in a compact US-ASCII representation and passes GitLab's regular expression validation. When evaluated against a specially formed, valid UTF-8 repository path, Ruby's Onigmo engine recompiles it for the new encoding after those checks have completed. An integer overflow in the compiler's program-size calculation causes invalid regular expression instructions to be generated; the resulting loss of control-flow integrity can be used to execute attacker-controlled Onigmo VM operations in the Ruby process and run an operating system command as the GitLab git user.

    Reported Source: Rapid7 blogView cited source
  7. [7]

    Rapid7 validated the complete chain against the official GitLab 19.4.1 CE Linux amd64 image with address space layout randomization enabled. The same input did not execute against the official patched 19.4.2 CE image.

    Reported Source: Rapid7 blogView cited source
  8. [8]

    As of Rapid7's October 13, 2026 post, there was no confirmed in-the-wild exploitation of CVE-2026-97229, and Rapid7 Intelligence had independently reproduced arbitrary code execution on an unpatched, official GitLab CE image.

    Reported Source: Rapid7 blog, October 13, 2026View cited source
  9. [9]

    Rapid7 said further root cause and exploit-chain details will be included in a separate Rapid7 technical analysis.

    Reported Source: Rapid7 blogView cited source
  10. [10]

    A prior GitLab max-severity flaw, CVE-2026-85706, saw in-the-wild probing within hours of public disclosure and was later added to CISA's KEV catalog.

    Reported Source: Orca Security research noteView cited source
  11. [11]

    GitLab.com is already running the patched version, and GitLab Dedicated customers do not need to take action.

    Reported Source: GitLab patch release noticeView cited source
  12. [12]

    Until affected self-managed instances can be upgraded, restricting anonymous access to public projects and preventing untrusted users from creating or writing to public projects can reduce exposure to the exploit path Rapid7 demonstrated. These controls address only the demonstrated delivery path and do not remediate the vulnerable regular expression compiler.

    Reported Source: Rapid7 blogView cited source
  13. [13]

    Orca says no authentication is required to exploit CVE-2026-97229 on instances that allow public project creation or user self-registration.

    Reported Source: Orca Security research noteView cited source
  14. [14]

    Orca says GitLab has published no workaround for the vulnerability, and recommends as interim mitigation disabling user self-registration where it is not needed.

    Reported Source: Orca Security research noteView cited source
  15. [15]

    Roman Y. Sannikov, global research coordinator at iCounter, said a self-managed GitLab server holds an organization's source code, its build pipelines, and usually the credentials those pipelines use to reach cloud accounts, package registries and production.

    Reported Source: Roman Y. Sannikov, iCounter, quoted by SC WorldView cited source
  16. [16]

    Sannikov said: "Teams should assume the window between disclosure and exploitation is days, not weeks," and pointed to scanning that started shortly after disclosure of GitLab's last 10.0 flaw.

    Reported Source: Roman Y. Sannikov, iCounter, quoted by SC WorldView cited source
  17. [17]

    Sannikov advised patching every self-managed instance, then looking at what a compromised instance could have reached: rotate CI/CD secrets and tokens, and review runner and pipeline activity since disclosure for anything unexpected.

    Reported Source: Roman Y. Sannikov, iCounter, quoted by SC WorldView cited source
  18. [18]

    Shane Barney, chief information security officer at Keeper Security, said that because exploitation requires no authentication and no user interaction, an attacker can use a specially crafted regular expression in a pipeline configuration file to execute arbitrary code directly on the underlying server.

    Reported Source: Shane Barney, Keeper Security, quoted by SC WorldView cited source
  19. [19]

    CVE-2026-14814 (CVSS 8.2), fixed in the same release, is a permissive regular expression vulnerability that could allow a user to poison cached responses for raw repository files, causing targeted users' CI/CD pipelines to execute specially crafted content and potentially exposing protected environment variables.

    Reported Source: GitLab patch release noticeView cited source
  20. [20]

    For security fixes, GitLab makes the issues detailing each vulnerability public on its issue tracker 90 days after the release in which they were patched.

    Reported Source: GitLab patch release noticeView cited source
  21. [21]

    Bloom Security researchers found that npm's Trusted Publishing feature let an attacker push new versions of someone else's package without stealing a credential. The attacker only needed to register a GitHub repository name the maintainer had left behind.

    Reported Source: Help Net Security, reporting Bloom Security researchView cited source
  22. [22]

    Bloom counted more than 1,500 npm packages exposed this way. The exposed packages have more than 10 million downloads in total and more than a million a month.

    Reported Source: Help Net Security, reporting Bloom SecurityView cited source
  23. [23]

    npm recorded the bound repository by its name, the owner/repo string GitHub calls a slug. GitHub also assigns every repository and owner a permanent numeric ID that survives renames and transfers, and puts both IDs in the token. npm did not check them.

    Reported Source: Help Net Security, reporting Bloom SecurityView cited source
  24. [24]

    For the attack (codenamed SlugFest) to succeed, the victim's trusted publisher must point to a GitHub slug an attacker can claim, and the repository must never have been used to publish a version of the package to npm. The attacker creates a repository at the freed slug (GitHub issues a fresh repository ID), triggers an npm publish workflow that mints an OIDC token carrying the reclaimed slug and the new ID, and submits it to npm's exchange endpoint; npm finds the repository claim matches the stored slug and issues a time-limited publish token for a package the attacker does not own.

    Reported Source: The Hacker News, reporting Bloom SecurityView cited source
  25. [25]

    Golan Myers of Bloom Security said: "It is like a lock that checks the address on the door rather than who owns the house: when the owner moves out, whoever moves in gets the key."

    Reported Source: Golan Myers, Bloom Security, quoted by The Hacker NewsView cited source
  26. [26]

    A release published through this flaw carries a valid provenance attestation, a signed build record, naming the attacker's repository.

    Reported Source: Help Net Security, reporting Bloom SecurityView cited source
  27. [27]

    GitHub retires the names of repositories with more than 100 clones in the week before an owner account is renamed or deleted, which protects some packages. Golan Myers, security researcher at Bloom Security, said: "We took this into account. Everything we considered vulnerable was pertaining to claimable slugs,"

    Reported Source: Help Net Security; Golan Myers, Bloom SecurityView cited source
  28. [28]

    Bloom reported the issue through GitHub's bug bounty program on HackerOne on June 6, and GitHub validated it on June 9.

    Reported Source: Help Net Security, reporting Bloom SecurityView cited source
  29. [29]

    Bloom says the last reply it got from GitHub was on July 8, and that six follow-ups after that, including a mediation request to HackerOne, went unanswered.

    Reported Source: Bloom Security, via Help Net SecurityView cited source
  30. [30]

    GitHub announced the change on October 2. GitHub's statement does not say whether configurations that published before the change were bound retroactively.

    Reported Source: Help Net SecurityView cited source
  31. [31]

    GitHub expires unvalidated npm trusted publishing configurations 48 hours after creation. Per GitHub: "Your configuration becomes validated and exempt from expiry after its first successful publish" and "Changing the repository or project identity requires a new trust relationship with a fresh 48-hour validation window."

    Reported Source: GitHub, quoted by The Hacker NewsView cited source
  32. [32]

    Golan Myers said it is unknown whether anyone exploited the flaw in the wild.

    Reported Source: Golan Myers, Bloom Security, via Help Net SecurityView cited source
  33. [33]

    If a malicious release includes a postinstall hook, its code can execute during installation on developer machines or continuous integration systems.

    Reported Source: The Next Web, reporting Bloom Security researchView cited source
  34. [34]

    Bloom says npm's GitLab trusted publishing integration has the same weakness.

    Reported Source: Bloom Security, via Help Net SecurityView cited source
  35. [35]

    Maintainers with Trusted Publishing should run npm trust list and confirm each listed repository still resolves to one they control, delete and re-create any binding that points at a renamed or transferred repository, and remove the binding before deleting a repository.

    Reported Source: Help Net SecurityView cited source
  36. [36]

    Bloom is not publishing the affected package names, so users cannot check against a list; they can verify that a package's provenance attestation names the repository the project is supposed to come from.

    Reported Source: Help Net Security, reporting Bloom SecurityView cited source
  37. [37]

    Based on telemetry from dozens of organizations, Bloom estimates that AI agents on a typical endpoint install about 70 packages a month, and close to 350 on developer machines, not counting dependencies. Those installs usually happen without a review of the package or its maintainer.

    Reported Source: Bloom Security estimate, via Help Net SecurityView cited source
  38. [38]

    Bloom ran the attack end to end on a package and repositories its researchers controlled, publishing from a second organization's repository that had claimed the freed slug.

    Reported Source: Help Net Security, reporting Bloom SecurityView cited source
  39. [39]

    GitHub's announcement came 118 days after Bloom's report.

    Derived
  40. [40]

    Ninety days after the October 12, 2026 release falls on January 10, 2027, when GitLab's issue tracker is due to make the fix details public.

    Derived

Sources & coverage · 7 publishers

The reporting this story was synthesized from, earliest first. Every link goes to the original.

  1. thenextweb.comKolawole Samuel Adebayo3d ago
    How AI coding tools could amplify software supply-chain attacks
  2. thehackernews.cominfo@thehackernews.com (The Hacker News)3d ago
    GitHub Tightens npm Publishing After Flaw Left 1,500+ Packages Vulnerable to Hijacking
  3. docs.gitlab.com3d ago
    docs.gitlab.com
  4. Cited in this coverage: Orca Security research note

Additional citations

  • GitLab critical patch release notice, October 12, 2026
  • GitLab patch release notice
  • GitLab advisory
  • Rapid7 blog, October 13, 2026
  • Rapid7 blog
  • Roman Y. Sannikov, iCounter, quoted by SC World
  • Shane Barney, Keeper Security, quoted by SC World
  • Help Net Security, reporting Bloom Security research
  • Help Net Security, reporting Bloom Security
  • The Hacker News, reporting Bloom Security
  • Golan Myers, Bloom Security, quoted by The Hacker News
  • Help Net Security; Golan Myers, Bloom Security
  • Bloom Security, via Help Net Security
  • Help Net Security
  • GitHub, quoted by The Hacker News
  • Golan Myers, Bloom Security, via Help Net Security
  • The Next Web, reporting Bloom Security research
  • Bloom Security estimate, via Help Net Security