Friday, August 11, 2023

Your GitHub Secrets Ain't That Secret: (GitHub actions hack)


Sometimes secrets in the real world aren't as secret as we think! Although it can be scary, it’s really easy to show the content of your secret in GitHub actions log. You might not mind if your repo is private but if it is public and your Open Source project still needs things to stay private like secrets, It’s a real liability.

In this blog post, we’ll reveal how seemingly hidden GitHub secrets can sometimes slip out in plain sight. All it takes is a tiny code snippet in my workflow. But first, let’s review some fundamentals about GitHub secrets. down pointing left hand index (brown)


GitHub Actions and Secrets 

  • Secrets in public repositories are automatically masked in build logs & show as strings of  "*" characters.

  • There are organization, repository and environment level secrets (contexts).

  • In case of  conflict, organization is overridden by repository and repository is overridden by env values.

    • secrets.GITHUB_TOKEN is a temporary token for each workflow run.

  • Beware: GitHub Actions logs of your public repo are visible to anyone as opposed to private ones.

Let’s crack your secret

cheers meme

                           What if the secret is already visible in your workflow log of your public repo? 

In order to run this test and show your secret in your build log. You can either

  • Clone my repo then load it back to your own GitHub.

  • Just reuse the code in my Workflow.


  • A repository + branch (optional)

    Example   Repo: brokedba/githubactions_hacks  Branch: git_actions


  • An environment
    Name: lab_tests , With deployment branch set to `selected branch`: i.e git_actions 

  • A Secret

    secret name:
    secret value: MYPassword

  • A workflow

You can download test_secret.yml located under .github/workflows as below display might not be properly indented.

# example: test secret” action that shows the spaced content of your secret

name: 'My_secret_test_Workflow'
    branches: [ "git_actions" ]
      - '.github/workflows/test_secret.yml'   

    runs-on: ubuntu-latest
    environment: test-labs
#Use default shell of the GitHub Actions runner     defaults:      run:
       shell: bash
    # Checkout the repository to the GitHub Actions runner
    - name: Checkout
      uses: actions/checkout@v3  

# Show how to print unmasked GitHub secrets to the console
     - name: Step 1 - Echo out a GitHub Actions Secret to the logs
      run: |
# ==> show masked value ******
        echo ${{ secrets.TEST_SECRET }}

        echo "Trick to echo GitHub Actions Secret:  "  

        # ===> show the real content with spaces 'M Y P a s s w o r d'
        echo ${{secrets.TEST_SECRET}} | sed 's/./& /g' 

  • The content has nothing more but a check out action and a tiny code snippet that consumes the secret.

  • We chose the push as trigger event and the git_actions as target branch

  • We set paths so anytime the yaml workflow is changed a pipeline is triggered 

  • Finally a simple sed expression piped into the “echo secret” command  

Workflow Execution result

                                               A little change commit for test_secret.yml and Voila!   

                                               My secret is now readable in plain sight on the build log

You are never safe

Now, this is just a small example of how your secret can be revealed in the logs and although you’d argue that no one is going to add this code in their workflow in purpose but there are many ways to infiltrate your Github pipelines and inject malicious code from an external PR to either extract secrets or damage your deployments or artifacts.
It could be due to misconfiguration of your workflows or by using untrusted actions from Marketplace.

What we already know

More Vulnerabilities

Exploitability and impact of untrusted input such as supply-chain compromise is real, Here are few examples

  • Any maintainer can update a branch or a tag, hence a corrupted Public actions@v1 can have an updated tag that has a malicious code inside & everyone will call the wrong release. Read more Here 

  • There a list of event context data that might be attacker controlled like issue, title, body, & comment

  • The attacker server can use the GitHub API to modify repository content, including releases.

  • The attacker can exfiltrate repository and organizational secrets other than the ones of the workflow by creating a new workflow via personal access token (PAT).

  •  By default, pull requests from first-time contributors require approval from a maintainer but following PR might be malicious

  • pull_request_target trigger event: will allow any PR submitted from a forked repo to run in the context of your main repository getting access to secrets and write access to the original repo

Detailed studies on GitHub actions Vulnerabilities

Best practices

Again if your workflow is in a public repo, remember below safety measures  ⏬  

  • Use commit hash(@sha1) as version tag when calling third-party actions to shield yourself.

  • You must only invite trustworthy outside collaborators.

  • Don't have any workflow with a pull_request_target trigger.

  • Avoid using untrusted public actions and if you have to always test them in dummy repos first.

  • Prefer OpenID Connect to access cloud resources 

  • GITHUB_TOKEN and PAT should always be granted the minimum required permissions

  • Don’t reference directly values that you don’t control like

  • Avoid run steps (inline script) and use external actions instead

  • Sanitize your input using environment variables

  • scan for secrets in the source code itself using ggshield-action

  • If you create a credential from a secret (e.g. base64 an API key), you should mask the new value so it doesn't leak.

  • Have the "Require approval for all outside collaborators" option for GitHub Actions turned on

Below is an excellent cheat-sheet on available security best practices


  • This blog post aimed to shed light on potential security pitfalls in GitHub Actions.

  • Even masked secrets can be uncovered with some clever tricks as shown in my workflow code snippet .

  • There are even more vulnerabilities out there as mentioned in the second part of this article

  • Again if your workflow is in a public repo, remember to apply the mentioned safety measures

  • You should always be careful about how you set up your workflows  

  • Next, I will write a post about cleaning up your GitHub action cache after use.

Stay tuned

No comments:

Post a Comment