Skip to content

fix: pin 6 unpinned action(s),extract 2 unsafe expression(s) to env vars#1297

Open
dagecko wants to merge 3 commits intodanielmiessler:masterfrom
dagecko:runner-guard/fix-ci-security
Open

fix: pin 6 unpinned action(s),extract 2 unsafe expression(s) to env vars#1297
dagecko wants to merge 3 commits intodanielmiessler:masterfrom
dagecko:runner-guard/fix-ci-security

Conversation

@dagecko
Copy link
Copy Markdown

@dagecko dagecko commented Mar 26, 2026

This is a re-submission of #1296, which was closed due to a branch issue on my end. Same fixes, apologies for the noise.

Security: Harden GitHub Actions workflows

Hey, I found some CI/CD security issues in this repo's GitHub Actions workflows. These are the same vulnerability classes that were exploited in the tj-actions/changed-files supply chain attack. I've been reviewing repos that are affected and submitting fixes where I can.

This PR applies mechanical fixes and flags anything else that needs a manual look. Happy to answer any questions.

Fixes applied

Rule Severity File Description
RGS-002 high .github/workflows/readme-updater.yml Extracted 1 unsafe expression(s) to env vars
RGS-002 high .github/workflows/remote-wordlists-updater.yml Extracted 1 unsafe expression(s) to env vars
RGS-007 high .github/workflows/wordlist-updater_api-endpoints-res.yml Pinned 1 third-party action(s) to commit SHA
RGS-007 high .github/workflows/wordlist-updater_awesome-list-of-secrets-in-environment-variables.yml Pinned 1 third-party action(s) to commit SHA
RGS-007 high .github/workflows/wordlist-updater_combined_directories.yml Pinned 1 third-party action(s) to commit SHA
RGS-007 high .github/workflows/wordlist-updater_combined_words.yml Pinned 1 third-party action(s) to commit SHA
RGS-007 high .github/workflows/wordlist-updater_default-passwords.yml Pinned 1 third-party action(s) to commit SHA
RGS-007 high .github/workflows/wordlist-updater_fuzzing_etc_files.yml Pinned 1 third-party action(s) to commit SHA

Additional findings (manual review recommended)

No additional findings beyond the fixes applied above.

Why this matters

GitHub Actions workflows that use untrusted input in run: blocks or reference unpinned third-party actions are vulnerable to code injection and supply chain attacks. These are the same vulnerability classes exploited in the tj-actions/changed-files incident which compromised CI secrets across thousands of repositories.

How to verify

Review the diff, each change is mechanical and preserves workflow behavior:

  • Expression extraction: Moves ${{ }} expressions from run: blocks into env: mappings, preventing shell injection
  • SHA pinning: Pins third-party actions to immutable commit SHAs (original version tag preserved as comment)

If this PR is not welcome, just close it and I won't send another.

@ItsIgnacioPortal
Copy link
Copy Markdown
Collaborator

@dagecko This looks interesting! Do you have another link for the incident report? The one you shared returns a 404 not found. I've also looked at the https://github.com/tj-actions/changed-files/ repo, and there don't seem to be any pinned issues nor security advisories that would highlight this.

ItsIgnacioPortal added a commit that referenced this pull request Mar 26, 2026
@ItsIgnacioPortal
Copy link
Copy Markdown
Collaborator

I have preemptively disabled all github actions until this issue is properly investigated.

@dagecko
Copy link
Copy Markdown
Author

dagecko commented Mar 27, 2026

Hey @ItsIgnacioPortal, thanks for looking into this. The broken link was from an earlier version of the PR template, apologies about that.

Here's the research doc: https://www.vigilantdefense.com/research/github-top-50k-repos-cicd-security-scan

For the tj-actions incident specifically, here are some good references:

The tj-actions/changed-files repo was cleaned up after the incident, which is why you won't find pinned issues or advisories there anymore. The attack compromised the action by force-pushing a malicious commit to the mutable version tag, which meant every repo referencing it by tag (instead of SHA) executed attacker code in their CI.

Also, we had a fork issue that closed the original PR (#1296). This one (#1297) is the resubmission with the same fixes. Sorry for the noise.

@dagecko
Copy link
Copy Markdown
Author

dagecko commented Mar 27, 2026

@ItsIgnacioPortal I really appreciate you taking this seriously. You'd be surprised how many people brush it off. It's been a long day of trying to get these fixed across projects, so it's refreshing to see someone act on it.

Here's a full breakdown of what we found and why it matters for SecLists specifically:

Finding 1: RGS-008 (High) - Secrets Directly Interpolated in run Blocks

Files: readme-updater.yml, remote-wordlists-updater.yml

These workflows use ${{ secrets.GITHUB_TOKEN }} directly inside run: blocks. GitHub Actions expressions get interpolated into the shell script before the shell sees them, which means the token value is baked into the script source code. If an attacker can influence the shell context (through another vulnerability, a compromised dependency, or log exposure), the token is right there in plaintext.

The fix moves the secret into an env: mapping so it's passed as a standard environment variable ($GITHUB_TOKEN) instead. Same behavior, but the token is no longer embedded in the script source. It's a one-line structural change.

Finding 2: RGS-007 (Medium) - Unpinned Third-Party Actions

Files: 6 wordlist-updater_*.yml workflows

All six reference ad-m/github-push-action@master. The @master tag is mutable, meaning the owner of that action (or anyone who compromises their repo) can force-push master to point at a malicious commit. Every workflow referencing @master would then execute that code with whatever permissions the job has, including your GITHUB_TOKEN with write access to SecLists.

This is exactly how the tj-actions/changed-files attack worked. The attacker force-pushed the version tag to a malicious commit, and every repo using that action executed attacker code silently.

The fix pins each action to its full 40-character commit SHA. The original version tag is preserved as a comment so you can still see what version it corresponds to. If ad-m/github-push-action is ever compromised, the pinned SHA won't resolve to the malicious commit.

What could happen if left unfixed:

SecLists is one of the most widely used security testing resources. If an attacker compromises ad-m/github-push-action, they could use your CI pipeline to push malicious content directly into the SecLists repo (since these workflows have write access). That means poisoned wordlists, payloads, or discovery lists distributed to thousands of security professionals who trust this repo. The supply chain impact would be significant.

The fixes in this PR are mechanical and preserve all existing behavior. You can review every change in the diff. Nothing changes functionally, it just closes the door on these attack vectors.

Full details on the RGS classification system: https://github.com/Vigilant-LLC/runner-guard/tree/main/rules

Happy to answer anything else.

- Chris

Cleaning up quoting on extracted env var references for consistency
and correctness.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants