供应链漏洞危及核心AWS GitHub仓库并威胁AWS控制台。
Supply Chain Vuln Compromised Core AWS GitHub Repos & Threatened the AWS Console

原始链接: https://www.wiz.io/blog/wiz-research-codebreach-vulnerability-aws-codebuild

## CodeBreach:AWS 控制台供应链漏洞 - 摘要 Wiz 研究团队发现了一个名为“CodeBreach”的关键漏洞,该漏洞存在于 AWS CodeBuild CI 流水线中,可能导致关键 AWS GitHub 仓库被接管,包括为 AWS 控制台提供支持的核心 AWS JavaScript SDK。该漏洞源于构建触发器过滤器中缺少正则表达式锚点,使得未经身份验证的攻击者能够泄露凭证并注入恶意代码。 利用该漏洞涉及注册一个与维护者 ID 匹配的 GitHub 用户 ID(“日食”现象),从而绕过访问控制。这使得 Wiz 研究人员获得了管理员权限,可能危及 SDK,并严重地危及 AWS 控制台本身——影响大量的云环境(66% 使用该 SDK)。 AWS 迅速修复了该问题,加强了 CodeBuild 并实施了新的拉取请求评论审批构建门,以防止不受信任的构建。此事件凸显了针对 CI/CD 配置错误的供应链攻击日益增多的趋势,如最近的 Amazon Q VS Code 扩展被攻破事件所示。 建议使用 AWS CodeBuild 的组织保护其 CodeBuild-GitHub 连接,使用细粒度的 PAT,并防止不受信任的拉取请求触发特权构建。这强调了对 CI/CD 流水线安全进行强化以防止高影响漏洞的必要性。

## AWS GitHub 仓库漏洞总结 最近一次安全漏洞影响了 AWS 核心 GitHub 仓库,可能威胁到访问 AWS 控制台。该漏洞源于一个有缺陷的正则表达式(regex),该表达式用于控制允许哪些用户 ID 在拉取请求上运行工作流操作。该正则表达式未正确锚定,导致攻击者可以创建 GitHub 账户,其 ID 与允许列表匹配,并执行恶意代码,包括泄露访问令牌。 这些令牌并未授予完全的管理员权限,但允许攻击者以管理员身份邀请新用户。该事件凸显了在安全环境中编写不良正则表达式的危险性——这是一个常见问题,可以使用静态分析工具检测到。 AWS 此后为拉取请求实施了新的“批准工作流运行”用户界面,GitHub 似乎也已采用该界面来解决该问题。该事件引发了关于依赖正则表达式进行安全保护、人工智能驱动的代码审查捕捉此类错误的潜力以及 GitHub 权限系统的讨论。
相关文章

原文

Wiz Research uncovered CodeBreach, a critical vulnerability that placed the AWS Console supply chain at risk. The issue allowed a complete takeover of key AWS GitHub repositories - most notably the AWS JavaScript SDK, a core library that powers the AWS Console. By exploiting CodeBreach, attackers could have injected malicious code to launch a platform-wide compromise, potentially affecting not just the countless applications depending on the SDK, but the Console itself, threatening every AWS account.

The vulnerability stemmed from a subtle flaw in how the repositories’ AWS CodeBuild CI pipelines handled build triggers. Just two missing characters in a Regex filter allowed unauthenticated attackers to infiltrate the build environment and leak privileged credentials. This post breaks down how we leveraged this subtle misconfiguration to achieve a full repository takeover, and provides key recommendations for CodeBuild users to harden their own projects against similar attacks.

Wiz responsibly disclosed all findings to AWS, who promptly remediated the issue. AWS also implemented global hardening measures within the CodeBuild service to prevent similar attacks. Most notably, the new Pull Request Comment Approval build gate offers organizations a simple and secure path to prevent untrusted builds. Read the AWS Advisory here.

This issue follows a familiar pattern seen in recent supply-chain attacks like the Nx S1ngularity incident, where subtle CI/CD misconfigurations lead to disproportionately impactful attacks. Just last July, a threat actor abused a similar CodeBuild issue to launch a supply chain attack against users of the Amazon Q VS Code extension. This growing trend underscores the urgent need for organizations to harden their CI/CD pipelines.

While no immediate action is required by downstream consumers of the affected AWS GitHub repositories, we strongly recommend all AWS CodeBuild users implement the following safeguards to protect their own projects against similar issues.

  • Prevent Untrusted Pull Requests from Triggering Privileged Builds:

  • Secure the CodeBuild-GitHub Connection

    • Generate a unique, fine-grained Personal Access Token (PAT) for each CodeBuild project.

    • Strictly limit the PAT's permissions to the minimum required, as listed here.

    • Consider using a dedicated unprivileged GitHub account for the CodeBuild integration.

Find Vulnerable CodeBuild Projects with Wiz

Wiz customers can find CodeBuild projects that trigger builds based on untrusted pull requests using this pre-built query in the Wiz Threat Intel Center.

Our investigation into AWS CodeBuild was sparked by the attempted supply-chain attack on the Amazon Q VS Code extension. In that incident, an attacker exploited a misconfigured CodeBuild project to compromise the extension’s GitHub repository and inject malicious code into the main branch. This code was then included in a release which users downloaded. Although the attacker’s payload ultimately failed due to a typo, it did execute on end users’ machines - clearly demonstrating the risk of misconfigured CodeBuild pipelines.

CodeBuild is a managed CI service that’s commonly connected to GitHub repositories, triggering builds on events like new pull requests. To interact with GitHub, CodeBuild requires GitHub credentials, which are, by default, present in the memory of the build environment. This creates a critical risk: if an attacker can compromise a single build, they are just a memory dump away from stealing credentials that often possess powerful permissions over the source repository.

To Build or Not To Build: The Pull Request Problem 

The most common way to compromise a CI build is through a pull request. An attacker forks the target repository, adds malicious code, and then opens a PR against the original project. If CodeBuild is configured to spawn builds on PR events, it will trigger a build based on the attacker's branch. In the vast majority of build systems like make or yarn, controlling the source code of a build process is enough to run arbitrary code. This is the exact mechanism the attacker exploited to compromise the Amazon Q extension.

To prevent this attack scenario, CodeBuild offers webhook filters - a set of rules that an event must meet to trigger a build. Back in August, these filters were the primary defense against untrusted pull requests. Among the available options, the go-to solution was the ACTOR_ID filter: an allow-list of approved GitHub user IDs that ensures only trusted users can trigger a build.

This seemed like a robust defense, but maintaining a list of user IDs can be cumbersome. We wondered: were organizations actually using this filter correctly?

To find out, we decided to search for GitHub repositories connected to Public CodeBuild projects. When set to public, CodeBuild projects expose their settings via a publicly accessible dashboard and automatically link to it in the status of any commit that triggers a build. From the dashboard, anyone can view the project's build logs and configurations - including the exact webhook filters being used.

An Apparent Dead End

Our initial scan was promising. We quickly found seven AWS-owned repositories with public CodeBuild pages. Of those, four were active and configured to run builds on pull requests:

At first glance, everything seemed secure. All four projects implemented an ACTOR_ID filter, locking down builds to a list of approved maintainers. It appeared to be a dead end.

But the filter's syntax, shown above, was unusual for a typical ID list. The user IDs weren’t separated by commas or spaces, but by a pipe | character. That small detail was the key: in regular expressions, the | character means "OR". Reviewing the documentation confirmed it: the filter wasn't a simple list, it was a regex pattern. And it had a fatal flaw.

The issue was simple but critical: the regex patterns weren’t anchored. Without the start ^ and end $ anchors to require an exact match, a regex engine doesn't look for a string that perfectly matches the pattern, but one that merely contains it. This meant that any GitHub user ID that is a superstring of an approved ID could bypass the filter.

This was a powerful primitive in theory, but its success depended on a practical question: is it possible to register a brand-new GitHub user ID that contained the ID of an existing user?

When IDs Align

The answer is yes, and it hinges on how GitHub assigns IDs. Every user is given a unique and sequential numeric ID. Early accounts from 2008 have 5-digit IDs, while accounts from recent years ballooned to 9-digit IDs. As this sequence of numbers grows, it's inevitable that shorter, older IDs appear as substrings within longer, newer ones.

Based on our tests, GitHub creates roughly 200,000 new IDs each day. At that rate, for any given 6-digit maintainer ID, a new, longer ID containing it would become available for registration approximately every five days

We dubbed this recurring window of opportunity an "eclipse" -- the moment a new, longer ID perfectly "shadowed" a trusted maintainer's ID.

All four AWS repositories had short maintainer IDs only 6 or 7 digits long, resulting in frequent eclipses that made them all valid targets. 

Catching an Eclipse: Winning the Race for a Target ID

Having confirmed that a new GitHub ID could contain a maintainer's ID, the challenge became operational: how could we claim a specific ID the instant it became available? This was practically a race condition against the entire world, with roughly two new GitHub users created every second. We needed a way to create a lot of GitHub users at once.

The standard user sign-up flow is protected by reCAPTCHA, making automated account creation impossible. We needed a different approach.

Attempt #1: Organizations for ID Sampling

Our first thought was to use the GitHub Enterprise API to create organizations, which share the same ID pool as users. While this could allow us to claim the target ID, GH organization accounts can't open pull requests, making them useless for the final exploit. It wasn't a total dead end though. We repurposed this API into an ID sampling tool: we could create an organization, check its ID to see how close we were to the target ID, and then immediately delete it.

The Breakthrough: The GitHub App Manifest Flow

The real breakthrough came from GitHub Apps. Creating an app generates a corresponding bot user (e.g. app-name[bot]) that can interact with pull requests. It’s also possible to automate app creation via the manifest flow. While it’s composed of a few steps, it can be made atomic: the app and its bot are only created when a final confirmation URL is visited. 

This allowed us to prepare hundreds of app creation requests in advance and then, at the precise moment, visit all their confirmation URLs simultaneously. 

With our strategy in place, it was time to execute. We routinely used the organization-creation API to sample the current GitHub ID, allowing us to accurately predict the moment of the eclipse. We also initiated the manifest flow for 200 new GitHub Apps, collecting their unique confirmation URLs. 

We waited until the live ID count was just ~100 IDs away from the target ID, and then visited all 200 URLs at once, triggering a flood of new bot user registrations. The target ID was 226755743, which contained a trusted maintainer ID for the aws/aws-sdk-js-v3 repository.

After the registrations completed, a quick check confirmed our success:

We’d captured a user ID that could bypass the ACTOR_ID filter, and the method was reliable enough to be successfully repeated for each of the four target repositories.

With our bot user able to bypass the ACTOR_ID filter, we were ready to execute the proof-of-concept. We chose to target the aws/aws-sdk-js-v3 repository, preparing a pull request that fixes a legitimate issue. Buried within the PR was the real payload: a new NPM package dependency designed to execute in the build environment and extract the GitHub credentials.

We submitted the PR, and soon after received a notification: a build had been triggered. Moments later, we had successfully obtained the GitHub credentials of the aws-sdk-js-v3 CodeBuild project. 

(If you're up for a challenge, try to find the commit in the PR that triggered the build.)

Our payload retrieved the GH token by dumping the memory of a process within the build environment. A previous memory dump mitigation in CodeBuild, which AWS implemented in response to the Amazon Q incident, overlooked this particular process. Following our disclosure, CodeBuild now protects this process as well. While this is a welcomed improvement, it isn’t bulletproof. GitHub credentials still reside in the build’s memory, and attackers with Linux privilege escalation exploits can circumvent memory protections. That’s why the most robust mitigation is using build gates to prevent untrusted builds from running in the first place.

The Blast Radius 

The credentials we obtained were a GitHub Classic Personal Access Token (PAT) belonging to the aws-sdk-js-automation user. For an attacker, this was the perfect user to compromise, as it regularly interacts with the repository and releases new versions to GitHub:

We quickly confirmed that the aws-sdk-js-automation user had full admin privileges over the repository. Initially though, our access was scoped by the token's permissions: repo and admin:repo_hook. To escalate privileges, we abused the token’s repo scope, which can manage repository collaborators, and invited our own GitHub user to be a repository administrator.

As administrators, we could now push code directly to the main branch, approve any pull request, and exfiltrate repository secrets.

This level of control provided a clear path for supply chain attacks. The JavaScript SDK is released on a weekly basis to GitHub and then to NPM. Abusing this frequent release schedule, attackers could have injected malicious payloads right before a release was published, compromising it. Just a month prior, a threat actor using this exact method successfully infected downstream users of the Amazon Q VS Code extension. 

While the Amazon Q incident was serious, the potential impact here was exponentially greater.  Based on our analysis, a staggering 66% of cloud environments include the JavaScript SDK - meaning two out of every three environments host an instance with the SDK installed. It’s an exceptionally prominent software library, and among its users is perhaps the cloud’s most critical application: The AWS Console itself. Moreover, the Console bundles recent SDK versions; the image below shows a request from the console which includes user credentials and uses an SDK version released just 18 days prior:

Beyond the aws-sdk-js-v3 repository, the token we obtained had full admin privileges over several other repositories related to the JavaScript SDK. Among them were three private repositories, including what appeared to be AWS’s private mirrors of the JavaScript SDK. At this point though, given the demonstrated takeover and its potential impact, we halted further research and immediately reported the issues to AWS.

Crucially, this vulnerability extended beyond the SDK. While we only performed the CI takeover on the aws-sdk-js-v3 repository, the same ACTOR_ID filter bypass was present in at least three other AWS GitHub repositories. Threat actors could have exploited these to compromise the GH credentials for three additional GH accounts. Two were automation accounts like aws-sdk-js-automation, but one was a personal GitHub account of an AWS employee.

This vulnerability is a textbook example of why adversaries target CI/CD environments: a subtle, easily overlooked flaw that can be exploited for massive impact. We've seen this exact pattern in the recent Nx S1ngularity and Amazon Q supply-chain attacks. 

This trend is no accident. Attackers are increasingly drawn to CI/CD systems because they represent an ideal target:

  1. They’re complex, making them prone to subtle misconfigurations;

  2. They handle untrusted data, often testing code from external contributors;

  3. They’re highly privileged, requiring powerful credentials to access code, publish artifacts, and deploy to the cloud.

This combination of complexity, untrusted data, and privileged credentials creates a perfect storm for high-impact breaches that require no prior access.

The success of recent attacks serves as a critical wake-up call. Adversaries have already shifted their focus to CI/CD pipelines, and defenders are trailing behind. Addressing this threat requires a joint effort: organizations need to reduce pipeline privileges and implement stricter build gates, and CI/CD platforms should make these secure baselines straightforward to adopt. For security teams, the first step is to enforce a simple yet powerful principle: untrusted contributions should never trigger privileged pipelines. 

AWS investigated all reported concerns highlighted by Wiz’s research team in "Infiltrating the AWS Console Supply Chain: Hijacking Core AWS GitHub Repositories via CodeBuild." In response, AWS took a number of steps to mitigate all issues discovered by Wiz, as well as additional steps and mitigations to protect against similar possible future issues. The core issue of actor ID bypass due to unanchored regexes for the identified repos was mitigated within 48 hours of first disclosure. Additional mitigations were implemented, including further protections of all build processes that contain Github tokens or any other credentials in memory. In addition, AWS audited all other public build environments to ensure that no such issues exist across the AWS open source estate. Finally, AWS audited the logs of all public build repositories as well as associated CloudTrail logs and determined that no other actor had taken advantage of the unanchored regex issue demonstrated by the Wiz research team. AWS determined there was no impact of the identified issue on the confidentiality or integrity of any customer environment or any AWS service.

We would like to thank Wiz’s research team for their work in identifying this issue and their responsible collaboration with us to ensure that our customers remain protected and secure.

August 25th, 2025 – Wiz Research reports the actor ID bypass and repo takeover to AWS. 

August 25th, 2025 – AWS and Wiz meet to review the findings and discuss mitigations.

August 27th, 2025 – AWS anchors the vulnerable actor ID filters and revokes the personal access token of aws-sdk-js-automation.

September 2025 – AWS implements additional hardening to prevent non-privileged builds from accessing the project’s credentials via memory dumping.

January 15th, 2026 – Public disclosure.

Hi there! We are Nir Ohfeld (@nirohfeld), Sagi Tzadik (@sagitz_), Ronen Shustin (@ronenshh), Hillai Ben-Sasson (@hillai), and Yuval Avrahami (@yuvalavra) from the Wiz Research Team (@wiz_io). We are a group of veteran white-hat hackers with a single goal: to make the cloud a safer place for everyone. We primarily focus on finding new attack vectors in the cloud and uncovering isolation issues in cloud vendors and service providers. We would love to hear from you! Feel free to contact us on X (Twitter) or via email: [email protected]

联系我们 contact @ memedata.com