Securing GitHub Actions With SonarQube: Real-World Examples


Securing GitHub Actions With SonarQube: Real-World Examples

The automation and convenience offered by GitHub Actions have made them an indispensable part of modern software development workflows. These powerful tools, however, are not immune to security vulnerabilities. At Sonar, we're excited to introduce you to our enhanced GitHub Actions analysis capabilities, designed to proactively identify and help developers remediate security weaknesses directly within their CI/CD pipelines.

By showcasing real-life examples of vulnerabilities SonarQube detected during our continuous scans of open-source projects, we will demonstrate the engine's capabilities and dive into the specific types of vulnerabilities that can arise in GitHub Actions and underscore their potential impact on your development environment and the security of your software supply chain. Understanding these risks is the first crucial step towards writing more secure and resilient GitHub Actions.

A compromised GitHub Action can have severe, case-by-case impacts that depend on various factors such as the action's permissions, the secrets it accesses, and the scope of the repository it runs in. An attacker who injects malicious code into a workflow can execute arbitrary commands on the runner environment, potentially allowing them to steal credentials (like cloud keys or personal access tokens), or tamper with the build and deployment process, which is a significant supply chain risk for downstream users.

Earlier this year, we saw an in-the-wild example in the Nx "s1ngularity" incident. In that specific case, a vulnerability in an Nx GitHub Actions workflow allowed an attacker to perform command injection and steal the project's npm publishing token. This critical initial step enabled the attacker to publish malicious versions of the popular Nx packages to the official npm registry, which in turn infected thousands of downstream developers and organizations. The malware then proceeded to steal thousands of credentials.

In this blog, we will cover the common use cases of command injection and code execution vulnerabilities, with an additional interesting pitfall that developers might fall into. Some of the vulnerabilities we disclosed are redacted as they are yet to be fixed, but the public ones are tracked as:

GitHub Actions live inside your GitHub project and are defined in YAML files under the directory. Each workflow outlines one or more jobs, and each job contains a series of steps, specifying what actions to take, when to trigger them (e.g., on a code push or pull request), and the environment in which they should execute. Acting as the blueprint for your continuous integration, deployment, and other automation tasks, making it easy to understand and manage your automation logic directly alongside your code

Commonly, GitHub Actions are used as Continuous Integration and Continuous Delivery (CI/CD) pipelines, performing tasks such as automated builds, tests, deployments, and more. However, they are capable of doing whatever developers can script, as they essentially provide a full containerized environment.

But as with every technology, there are some risks involved; if not used safely, attackers might exploit vulnerable workflows and potentially lead to a devastating impact for their victims. GitHub does emphasize the importance of security and best practices when writing workflows; they provide official documentation and explanations on the topic. Despite their best efforts, developers might still make mistakes. This is where SonarQube comes in. With our new analyzer, we started supporting static scanning of your GitHub actions, and the best part is that it's completely free for open-source projects!

Let's dive into the details, starting with a straightforward case. SonarQube reported a command injection vulnerability in the following workflow:

Here, when a new issue is created, the workflow is triggered. During its execution in the command, the code interpolates the issue's title into the shell command line. Every GitHub user can open an issue in this public repository, so the variable should be treated as untrusted input. Because there is no sanitization and the string is simply interpolated into the command line, an attacker can create an issue with a command injection payload in the title that will then execute in the context of the action runner.

As a rule of thumb, GitHub recommends that every content field that ends with , , , , , , , , , and should be treated as untrusted.

The second example is similar to the first finding; however, this is using the event trigger. From a security standpoint, the difference between and is crucial. Workflows triggered by run in the context of the pull request branch, having a limited read-only . Conversely, workflows triggered by run against the base branch of the repository and can have write access to the repository's contents and secrets via the . This elevated permission level means that a successful exploit using a workflow can lead to a severe supply chain compromise, potentially allowing an attacker to modify the repository's code, publish releases, or steal secrets, even from an untrusted contributor's pull request. The severity of this risk, however, is highly dependent on the repository's configuration, specifically the branch protection rules on the base branch and the explicit permissions defined for the workflow's .

Try it yourself in SonarQube Cloud

This finding showcases a straightforward vulnerability as the is taken from the untrusted branch name, which can contain a command injection payload. Following our report, the downstream project has fixed the issue using the official best practices mitigation.

When looking at the official best practices for mitigating command injections, GitHub recommends adding the untrusted fields into an environment variable and then using that in the command line. This will prevent the untrusted data from being interpreted as executable code by the shell, as the contents of the environment variable are typically passed as a single argument or value:

Despite the comprehensive explanations given by GitHub, there is an interesting pitfall that developers might fall into. Especially when this pitfall is given as an example by GitHub in their official documentation, not when using untrusted input:

Did you notice the subtle difference?

The environment variables in the second example are used in the command line as such: instead of . While in this case the environment variable isn't controlled by an untrusted user, the interpolation here is performed in an unsafe manner because it uses GitHub Actions' context and expression syntax () to insert the environment variable's value before the job is sent to the runner's shell for execution. This bypasses the shell's built-in defense mechanism that typically handles environment variables, meaning that if this environment variable were user-controlled, this would have been a valid vulnerability.

And to demonstrate this, SonarQube detected such a vulnerability in serverless-dns:

The final major vulnerability we will cover is Code Execution within GitHub Actions workflows. Unlike the direct and easily identifiable signs of Command Injection (e.g., untrusted input in a shell command), this vulnerability is often harder to detect as it relies on ambiguous commands, or third-party Actions being executed on user-controlled code.

Consider the following workflow example with the SonarQube report, taken from an undisclosed project:

While there is no obvious command injection flaw, the combination of three critical steps creates a high-severity vulnerability:

This case is a clear example of checkout code being executed. However, many times developers may not be aware of what the third-party GitHub Actions are actually doing behind the scenes. The hidden nature of this type of vulnerability makes it a far more insidious and challenging supply chain risk than traditional command injection. Because developers often trust the actions they import from the GitHub Marketplace or verified vendors, they may not scrutinize what those actions do when pointed at untrusted, user-controlled code.

This blog post highlights the critical security risks inherent in using GitHub Actions and introduces SonarQube's enhanced analysis capabilities designed to detect and help remediate these vulnerabilities directly within CI/CD pipelines. We took a closer look at the technical details of some vulnerabilities and showcased the power of SonarQube by using real-world examples of vulnerabilities we found with it.

A compromised action can lead to severe consequences, including the theft of credentials and the potential for a full-scale software supply chain attack, as demonstrated by the high-profile Nx "s1ngularity" incident, where a vulnerability allowed command injection and the theft of an npm publishing token. Understanding these risks is essential for developers.

Previous articleNext article

POPULAR CATEGORY

corporate

15365

entertainment

18572

research

9347

misc

17999

wellness

15309

athletics

19673