Blog

Capturing Secrets from Environment Variables via CircleCI

by
Isaac Madan
,
June 5, 2023
Capturing Secrets from Environment Variables via CircleCICapturing Secrets from Environment Variables via CircleCI
Isaac Madan
June 5, 2023
Icon - Time needed to read this article

CircleCI is a platform that enables continuous integration and delivery of software projects. It allows teams to automate their software development process by building, testing, and deploying their code changes in a consistent and reliable manner. In this blog post, we will explore the Tactics/Techniques/Procedures (TTP) of how environment variables that house sensitive credentials and secrets can be exfiltrated using Circle CI.

Secrets Exfiltration Tactic

When one thinks about the risk of secrets in GitHub repos, the immediate concern is around hardcoded secrets that are committed to the codebase. For example, if you had a line of code saying API_KEY = abcde then this is the equivalent of storing your password in plaintext for all to see. Secrets detection tools are built to find secrets that are hardcoded in the codebase, and are essential for strong code security. The alternative to hardcoding secrets is to use environment variables and referencing them at build or runtime. Tools like Circle CI build software and have secrets and keys stored as environment variables stored within them. If a bad actor has write access to repos and can insert code that prints out environment variables to the logs at build-time, they will be able to access secrets that are used in the build without ever requiring any secrets to have been hardcoded in the code repositories in the first place. For example, many builds produce artifacts such as docker containers that need to be pushed to a central repository in the cloud, like Amazon ECR or DockerHub. To do this, the build system needs authentication variables, which are often put in the environment to avoid committing them to source control. These AWS or DockerHub keys could be vulnerable if an adversary had the ability to change the build *****steps***** through the environment, even if they did not have access to the vault where they are stored or updated. Or if the config is already printing variables out to the logs, a bad actor with access to Circle CI can see these secrets easily. This means a solution that’s searching the codebase for secrets would not catch this bad actor.

Circle CI Config

Here’s how it works in more detail. The CircleCI configuration file (often called .circleci/config.yml is a YAML file that defines the configuration for your builds, tests, and deployments in CircleCI. This file contains all the information necessary to define the environment, dependencies, and steps required to run your builds and tests. The configuration file is divided into sections that define different aspects of your build process, such as the environment, the jobs to run, the steps to execute in each job, and the workflows to define the order and dependencies of the jobs. Here is an example of a simple CircleCI configuration file:

yaml

version: 2.1

jobs:
  build:
    docker:
      - image: ubuntu:20.04
    steps:
      - checkout
      - run: echo "Hello, CircleCI!"

workflows:
  build_and_test:
    jobs:
      - build

In this example, we define a single job called build that runs in a Docker container based on the Ubuntu 20.04 image. The job consists of two steps: checking out the source code and printing a message to the console. We can specify in this config file various calls that print out environment variables to the build logs.

Printing Environment Variables

To print out environment variables in Circle CI, you can use the echo command along with the syntax for accessing environment variables in your shell. For example, to print the value of the MY_ENV_VAR environment variable, you can use the following command in your CircleCI configuration file:

yaml

- run: echo $MY_ENV_VAR

This will print the value of the MY_ENV_VAR environment variable to the CircleCI build logs. If you want to print out all the environment variables available to your CircleCI build logs, you can use the following command:

yaml

- run: printenv

This will print out a list of all the environment variables available to your CircleCI runner, along with their values, for example:

yaml

TERM_PROGRAM=Apple_Terminal
SHELL=/bin/zsh
TERM=xterm-256color
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
TMPDIR=...

If you run printenv command in CircleCI, the output will be displayed in the build logs. You can access the build logs from the CircleCI web interface or from your local terminal if you are running the CircleCI CLI.

Viewing the Logs

To view the build logs from the CircleCI web interface, follow these steps:

  1. Navigate to the project that you want to view the build logs for.
  2. Click on the "Builds" tab.
  3. Find the build that you want to view the logs for and click on it.
  4. The build logs will be displayed in the "Logs" tab.

If you are using the CircleCI CLI, you can use the circleci build logs command to view the build logs. For example:

bash

circleci build logs <BUILD_NUM>

Replace <BUILD_NUM> with the build number that you want to view the logs for. This command will display the build logs in your terminal. You can use standard Unix tools like grep and awk to filter and format the output as needed. For example, you can use the following command to filter the printenv output for a specific environment variable:

bash

circleci build logs <BUILD_NUM> | grep MY_ENV_VAR

How to Address This

To detect this TTP, we need to ensure our secrets detection solution is looking for more than just secrets themselves. If we are using a configurable solution like Nightfall, we can configure a detector that looks like printenv and specific echo statements in the codebase. For example, we could simply use the regex /printenv/ as a starting point, and we can add to it to hone it further. It’s unlikely that there should be code in config files that are printing the environment variables to logs — even if this isn’t malicious, doing so can lead to secrets ending up in application logs and other locations that are hard to clean up. So, with this detector configured we’ll be able to find instances of printed environment variables and remove these from the codebase.

Conclusion

Build pipelines present an interesting opportunity to print and log environment variables that represent sensitive credentials and secrets. You’re now equipped with a better understanding of this TTP and the steps you can take to combat any malicious actor looking to intercept credentials in your build pipeline.

On this page
Nightfall Mini Logo

Getting started is easy

Install in minutes to start protecting your sensitive data.

Get a demo