GitLab's incoming email address is a non-expiring token that commits code and runs CI as you
Aikido Security showed that the personal address GitLab issues for creating issues by email can also open merge requests that GitLab commits in your name and can start CI jobs, with no expiry and no MFA. GitLab calls it intended behavior.
Aikido Security disclosed on September 23 that the private email address GitLab gives each user for creating issues by email works as a credential. Changing the address suffix from -issue to -merge-request lets anyone who knows it email a patch that GitLab commits in the user's name, to any branch that user can push to, including main, and start CI/CD jobs that run as them. The token behind the address does not expire, covers every project the account can open, and bypasses IP restrictions and two-factor authentication, because GitLab does not check who sent the email. It affects GitLab.com and self-managed instances with incoming email configured. Aikido reported it through HackerOne in May; GitLab closed it as intended behavior, updated its documentation, and opened an issue to consider sender verification. Users can reset the token from their access tokens page; administrators can disable incoming email instance-wide.
Why it matters
Most token inventories would miss this one because it does not look like a token. It looks like an email address, which is exactly why people paste it into READMEs, support tickets and wiki pages to make "email us to open an issue" work. It is a bearer credential with write access to every project the user can reach, no expiry, and no second factor, so it belongs in the same inventory and rotation process as personal access tokens and deploy keys. See static API key abuse.
Two checks this week. Search your public documentation and ticket systems for GitLab incoming email addresses, and reset the token for any account whose address has ever been shared. Then look at branch protection: requiring an approved merge request limits which branches a mailed patch can land on, but it does nothing about the CI jobs that run as the user, which is where secrets live. This is the same shape as coding agents reaching CI secrets through a GitHub issue: an input channel nobody classified as an authentication path. See secrets in repositories and CI.
Source: The Hacker News
Related on Start with Identity
- BlogOne ConnectWise app credential opened Microsoft 365 tenants across MSP customers
Huntress found an attacker signing in as the ConnectWise Cloud Backup (formerly SkyKick) Entra app with a stolen app credential, pulling Microsoft Graph tokens
- BlogShai-Hulud reaches the Tensorlake npm SDK, with a wiper that fires when you revoke the stolen token
tensorlake@0.5.144, published from the project's own release workflow after commits pushed under a maintainer's name, carried a ChainDrop/Shai-Hulud credential
- BlogMicrosoft names Storm-0940 behind ConnectWise app abuse that reached 2,250 Microsoft 365 tenants
Microsoft said on October 21 that China-aligned Storm-0940 used the ARTEX agentic AI framework and stolen ConnectWise application identities to try signing in t
- CVEOver-scoped CodeBuild GitHub token let an attacker ship code in Amazon Q Developer 1.84.0
An inappropriately scoped GitHub token in the CodeBuild configuration for the Amazon Q Developer VS Code extension let an attacker commit code that shipped auto
- CVEtj-actions/changed-files tags repointed to dump CI secrets into logs
An attacker repointed tj-actions/changed-files version tags to a commit that read the GitHub Actions runner's memory and printed its secrets into workflow logs.
- CVETrivy release and GitHub Action tags hijacked to steal CI secrets
With credentials left valid by a non-atomic rotation, an attacker shipped a malicious Trivy v0.69.4 and repointed 76 of 77 trivy-action tags to code that dumped