Light bulb Limited Spots Available: Secure Your Lifetime Subscription on Gumroad!

Sep 25, 2026 · 9 min read

GitLab Email Addresses Let Attackers Push Code to Main

Aikido Security researcher Joe Leon showed on September 23, 2026 that the private address behind GitLab's "Email work item to this project" button carries an account wide glimt token. Swap one suffix and the same address opens merge requests, applies patches, and runs CI jobs as the token owner, even from outside an IP allowlist.

Maintainers put it in the README so users know where to send bug reports. It looks like any other contact address. It is actually a password. In a write up titled "Send GitLab an email, push to main", Aikido Security tested it against a private project locked to a single IP address that wasn't theirs. "GitLab blocked our browser and rejected git clone. It accepted the email, and the commit landed on main."

Key Takeaways

  • GitLab's "Email work item to this project" address embeds a glimt- incoming email token that, according to Aikido Security, is tied to the whole account and never expires.
  • Changing the address suffix from -issue to -merge-request lets any sender open merge requests with attached .patch files, which GitLab applies to a branch named in the subject line.
  • Aikido confirmed pushes to a protected branch, CI/CD secret reads, and confidential issue access in private projects it controlled, all from an email.
  • GitLab's own documentation states that incoming email is not subject to IP restrictions, and a separate page says it works without two factor authentication even where 2FA is enforced.
  • Aikido found a dozen live addresses published in READMEs and contributing guides in a single afternoon; the only fix is resetting the token, which invalidates every project address on the account.

What Is the GitLab "Email Work Item" Address?

It is a per user email address that creates an issue in a GitLab project, authored by you, whenever anyone mails it. GitLab's issue documentation places it under Plan > Work items > More actions > Email work item to this project, and says the subject becomes the issue title while the body becomes the description. The same page suggests you can "save this address as a contact in your email client to use it again."

Aikido published the format with the secret redacted:

incoming+project-id-glimt-XXXXXXXXXXXXXX-issue@incoming.gitlab.com

The glimt- string is the credential. The UI shows a different address in every project, which suggests each one is scoped to that project. Aikido opened the dialog in five projects and got five addresses, but "the glimt- token embedded in each one is identical, in private projects too." The address changes. The key inside it doesn't.

GitLab also does not check who sent the message. In Aikido's words: "Any mailbox on the internet can send to that address, and GitLab processes the message as the token's owner." Holding the address gives an attacker both authentication and authorization.

How Does an Issue Address Become a Code Push?

An attacker swaps -issue@ for -merge-request@ and attaches a git patch, and GitLab commits it to whatever branch the subject line names. The merge request feature is documented. GitLab's merge request docs explain that the subject is the source branch name, that attachments must end in .patch and total 2 MB or less, and that a missing source branch "is created from the repository's HEAD, or the default target branch."

Aikido laid out the full chain:

  1. A maintainer publishes or leaks a project's issue by email address.
  2. The attacker changes the suffix to -merge-request@.
  3. The attacker writes a patch that adds a job to .gitlab-ci.yml, with no knowledge of the target repository.
  4. The attacker emails the patch with the source branch in the subject line. GitLab pushes to that branch, creating it if needed.
  5. GitLab runs the job in the victim's project, as the victim.

The CI job is one payoff. The other is a commit on any branch the victim can push to, main included, authored under the victim's name. Anyone who builds from that repository then ships the attacker's code.

Why Don't IP Allowlists Stop It?

IP allowlists filter HTTP and SSH traffic, and GitLab's mail intake is a separate path that the allowlist never sees. The group access and permissions documentation now says so directly: users "can create issues and merge requests by email with their incoming email token, because incoming email is not subject to IP restrictions." That sentence was one of the changes GitLab made after Aikido's report.

There is a second bypass that Aikido's post doesn't mention. GitLab's incoming email administration page states: "Users can use the incoming email features without having to use two-factor authentication (2FA) to authenticate themselves first. This applies even if you have enforced two-factor authentication for your instance." A self managed admin who enforced 2FA and restricted a group to the corporate VPN has closed the web and git doors, while the mail slot stays open with a bearer token as its only lock.

Laptop on a desk at night showing a code diff beside an email inbox, illustrating a GitLab merge request sent by email

What Can One Leaked Address Reach?

One address can reach every project the token owner can, with the owner's full role. Aikido says it confirmed each of these paths against projects it controls:

  • Pushing code to a protected branch in a private repository behind an IP allowlist
  • Exfiltrating source code from private projects behind an IP allowlist
  • Reading CI/CD variables and secrets from private projects
  • Accessing confidential issues in private projects via the /move quick action
  • Using the CI_JOB_TOKEN available in CI/CD jobs to reach further into the account

Two limits apply. The token inherits the victim's permissions and nothing in the mail path raises them: "A leaked Guest address is pretty much worthless. A leaked Maintainer address could reach protected branches and CI/CD variables." And routing needs a project path slug plus a project ID. GitLab publishes both for public projects, and Aikido notes the ID of a private project "is guessable."

Those limits are thinner than they sound. The people most likely to publish a bug report address are maintainers, the exact role Aikido identifies as dangerous. BleepingComputer's coverage frames this as a supply chain risk, and the pattern mirrors the long lived CISA cloud keys that sat in a public GitHub repo: a secret published in plain sight because nobody recognized it as one.

How Did GitLab Respond?

GitLab treated the report as intended behavior, then changed its wording rather than the mechanism. Per Aikido's disclosure section:

  • May 2026: Aikido reported through HackerOne. The report was closed as intended behavior.
  • June 2026: Aikido filed a confidential issue on the GitLab repository and received a more detailed response.
  • July 28, 2026: Aikido's screenshots from this date still show the old UI. The personal access tokens page then said the incoming email token "cannot be used to access any other data."
  • Afterward: GitLab removed that sentence, added "and merge requests" to both UI surfaces, and documented that incoming email is not subject to IP restrictions.
  • September 23, 2026: Aikido published after notifying the affected accounts it found.

Sender validation is still missing. Aikido says GitLab is "now considering" checking that the sending address matches the token owner, which it calls the single biggest reduction in attack surface. Users also cannot disable issue or merge request creation by email, and GitLab has no way to bulk revoke these tokens or notify affected users. The HackerOne closure echoes June, when GitHub closed reports on design flaws behind the Shai-Hulud worm.

Why Email Users Should Care

Most email security advice assumes an address is public and a password is private. This token breaks that split. Email addresses exist to be copied, forwarded, pasted into signatures, and saved into address books. GitLab itself tells users to save this one as a contact. Once saved, it can sync to every device and app with contacts access, and it sits in the Sent folder of every thread you used it in.

Follow that through. A mailbox takeover of a developer's Gmail or Outlook account now yields more than the inbox. A search for glimt or incoming.gitlab.com in Sent mail or Contacts could surface a GitLab credential that ignores 2FA enforcement and IP allowlists. That is the same pivot we saw when a dormant OAuth token let attackers into Salesforce: one forgotten credential opening a much larger system.

The address family has been abused before, in the other direction. In September 2017, researcher Inti De Ceukelaire used a GitLab issue by email address to join GitLab's own Slack workspace, because Slack trusted any @gitlab.com address. GitLab still cites that case, issue #30366, in its incoming email docs. In 2017 a third party treated the address as proof of identity. In 2026 GitLab treats it as proof of identity itself.

What Should GitLab Users Do Now?

Reset your incoming email token unless you actively use it, then hunt down anywhere the old address was published. Concrete steps:

  • Reset the token. Aikido points to the reset link on the Personal access tokens page under User settings, which invalidates every project address at once. The issue docs also offer a "reset this token" link inside the Email issue to this project dialog.
  • Search your repos and docs. Grep READMEs, CONTRIBUTING files, wikis, and support pages for glimt- and for incoming+ addresses ending in -issue@ or -merge-request@. A glimt- search alone isn't enough: Aikido notes that custom prefixed tokens and tokens minted before the glimt- prefix existed also appear, and says it added all three formats to the open source Betterleaks scanner.
  • Search your mailbox. Look through Sent mail and Contacts for the same strings, and delete saved copies after you reset.
  • Use Service Desk for public intake. Service Desk gives outsiders a project address without needing GitLab accounts. Per the configuration docs, tickets are created by a Support Bot user and are confidential by default, and the example address (incoming+group-project-12346426-issue-@incoming.gitlab.com) contains no personal token. GitLab lists the feature as not under active development.
  • Shrink the blast radius. The token can only do what its owner can do, so limit who holds Maintainer rights and who can push directly to main. Marking CI/CD variables as protected makes them "only available in pipelines that run on protected branches or protected tags," per GitLab's CI/CD variables docs, which keeps them out of jobs on freshly created branches.
  • Stop treating IP allowlists as a hard boundary. Aikido's advice is blunt: they "don't block when users push code via email."

The fix Aikido wants, matching the sender to the account's verified address, would force an attacker to compromise your mailbox instead of just reading your README. Until GitLab ships it, treat every GitLab incoming address like an API key that happens to have an @ sign in it.

Stop Email Tracking in Gmail

Spy pixels track when you open emails, where you are, and what device you use. Gblock blocks them automatically.

Try Gblock Free for 30 Days

No credit card required. Works with Chrome, Edge, Brave, and Arc.