TL;DR: From an unprivileged CodeBuild job using CodeConnections you can hit an undocumented API to retrieve the raw GitHub App token or BitBucket JWT App token CodeConnections uses. These tokens can be used directly against GitHub/BitBucket APIs and have the full permissions of the CodeConnection App you installed into your GitHub/BitBucket. In GitHub and BitBucket, the CodeConnection App has read, write and administration permissions (in most cases) on all repositories under your organisation. The administration permission allows branch protections and other source code provider protections to be disabled by an attacker allowing them to directly write to your organisation repositories and infecting application code, CI/CD workflows and IaC across your 1000s of repositories. If you use CodeConnections but not CodeBuild then you are still susceptible as an attacker could spin up a new CodeBuild job in your AWS account to grab the tokens given the right permissions. Mitigating the issue requires preventing the use of CodeConnections with CodeBuild via blocking codestar-connections:GetConnectionToken and codeconnections:GetConnectionToken permissions which is best achieved via an SCP. In this series of blogposts we’ll be taking an in-depth look at the security of AWS CodeConnections and their use in several different AWS Services. As CodeConnections become supported in more AWS services, it is important for us to understand exactly how CodeConnections work, what their limitations are and what security controls can be applied to ensure our code repositories and infrastructure stays secure. This series of blog posts aims to answer the question, can we significantly escalate our privileges via the source code provider permissions granted to AWS if we can compromise a single AWS account or single AWS service such as CodePipeline. You can view all the posts in this series by visiting my AWS CodeConnection project page . In the first post of the series we covered a primer on AWS CodeConnections and the Apps that are installed into the source code providers. We focused on what permissions AWS CodeConnection gets and the limitations on restricting these permissions. In this post we will be looking in depth at how AWS CodeBuild uses CodeConnections. During the course of my research presented in this blog post I have engaged with AWS Security via their VDP and worked with them through the disclosure process. An official response from AWS and disclosure timeline can be found at the end of this post. What is AWS CodeBuild According to AWS, CodeBuild is a fully managed build service in the cloud. For those not familiar, you can think of it as cloud-hosted compute that can take input, run some build commands and then output an artefact. How does CodeBuild work with CodeConnections? The first step in most CodeBuild projects is to obtain some source code. You then run your build commands on top of this source code. CodeBuild can pull source code from several different places such as S3, GitHub, etc. When specifying the source location of GitHub, GitLab or Bitbucket, CodeBuild will allow you to use a few different authentication methods: CodeConnection OAuth connections Personal access tokens In this post we are going to focus on using CodeBuild with GitHub, Bitbucket and GitLab via the CodeConnection option. IAM Role When creating a CodeBuild project using a CodeConnection via the console it will create an IAM role for you. It has the following permissions: { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "codestar-connections:GetConnectionToken", "codestar-connections:GetConnection", "codeconnections:GetConnectionToken", "codeconnections:GetConnection", "codeconnections:UseConnection" ], "Resource": [ "arn:aws:codestar-connections:REGION:ACCOUNT_ID:connection/CONNECTION_ID", "arn:aws:codeconnections:REGION:ACCOUNT_ID:connection/CONNECTION_ID" ] } ] } As can be seen, it adds both the CodeStar scoped permissions and the CodeConnection scoped permissions for backwards compatibility with the old naming format and there are 3 different permission actions. Exploring these permissions we find that: The GetConnection permission is used when setting up the CodeBuild project but not during a build. Updating a CodeBuild project will fail if this permission is missing from the CodeBuild service role. The UseConnection permission is only used when the CodeConnection is of type GitLab (as we’ll discuss later). It is not needed if you are using GitHub or BitBucket. The GetConnectionToken permission is used when the CodeConnection is of type GitHub or BitBucket. Therefore, in most cases (excluding GitLab) during the actual build of a CodeBuild project, only the GetConnectionToken permission is used. This permission sounds interesting and we’ll be exploring it later. Exploring a CodeBuild build Now we are going to explore the build environment like we did in the CodePipeline post. To do this we’ll again setup a reve...
An undocumented API endpoint in AWS CodeBuild, when used with CodeConnections, allows an unprivileged CodeBuild job to extract the raw GitHub App or BitBucket JWT token used by the connection, granting the attacker the connection's full administrative permissions on the source code provider. This enables lateral movement and privilege escalation by allowing direct modification of repositories, CI/CD workflows, and IaC across an organization. The recommended mitigation is to block the `codestar-connections:GetConnectionToken` and `codeconnections:GetConnectionToken` permissions via an SCP to prevent token retrieval.