The TJ Actions Changed Files supply chain attack exposed critical vulnerabilities in GitHub Actions workflows, highlighting the risks of relying on third-party actions. This incident underscores the urgent need for robust security practices to protect CI/CD pipelines from similar threats.
In this blog, we’ll delve into GitHub Actions security, explore common risks, and provide actionable best practices and advanced hardening techniques. Whether you’re a security professional or a leader, this guide will equip you with the knowledge to secure your workflows and mitigate supply chain risks.
GitHub Actions is a powerful CI/CD platform that automates workflows triggered by events like push, pull requests, or scheduled tasks. Workflows are defined in YAML files (e.g., .github/workflows/main.yml) and can include steps for building, testing, and deploying code.
Example workflow:
yamlname: CI Pipeline on: [push] jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Run tests run: npm test
For a comprehensive overview, refer to the FAQs 1 & 2.
Always use actions from trusted sources, such as official GitHub repositories or verified publishers. Additionally, verify the integrity of actions by reviewing their source code and commit history.
Example of using a trusted action:
yaml- uses: actions/checkout@v3
For more guidance, refer to the FAQs 3 & 4.
Pinning dependencies to specific versions or commit hashes prevents unauthorized updates and reduces the risk of supply chain attacks.
Example of pinning an action:
yaml- uses: tj-actions/changed-files@a1b2c3d4e5f6g7h8i9j0
Regularly monitor workflows for suspicious activity using GitHub’s audit logs and third-party tools. Implement automated alerts for unusual behavior, such as unexpected changes to workflow files or unauthorized access attempts.
Example of monitoring with GitHub Actions:
- name: Audit Workflow
run: |
echo "Checking for suspicious activity..."
gh audit-log --event workflow --action created
Static analysis tools like Semgrep and Endor Labs can scan workflows for vulnerabilities, such as hardcoded secrets or malicious code.
Example Semgrep rule to detect hardcoded secrets:
yamlrules: - id: "hardcoded-secret" pattern: | $SECRET = "..." message: "Hardcoded secret detected."
Restrict permissions for GitHub tokens and secrets to minimize the impact of potential breaches. Use the permissions keyword to define granular access controls.
Example of least privilege permissions:
permissions:
contents: read
actions: read
A Software Bill of Materials (SBOM) provides transparency into the components and dependencies used in your workflows. Tools like Ion Cloud Security Platform and Anchore can generate SBOMs for GitHub Actions.
Example of generating an SBOM using a module under vulnerability monitoring on Ion Cloud Security platform:
syft: ghcr.io/your-repo/your-action:latest -o spdx-json > sbom.json
actions: read
For more on SBOMs, refer to the FAQs 7 & 8.
The TJ Actions Changed Files incident serves as a wake-up call for securing GitHub Actions workflows. By adopting best practices like using trusted actions, pinning dependencies, and implementing least privilege principles, you can significantly reduce the risk of supply chain attacks.
Advanced techniques, such as leveraging static analysis tools and SBOMs, further enhance your security posture. As security professionals and leaders, it’s our responsibility to stay proactive and ensure the integrity of our CI/CD pipelines.
By taking these steps, you can safeguard your workflows, protect your organization, and contribute to a more secure open-source ecosystem.
GitHub Actions runners are the machines that execute your workflows. They can be hosted by GitHub (GitHub-hosted runners) or self-hosted on your infrastructure. Each runner picks up jobs from the workflow queue and executes the steps defined in your YAML file.
Yes, GitHub Actions is highly versatile and can be used for a variety of tasks beyond CI/CD, such as automating issue management, sending notifications, or deploying infrastructure. Workflows can be triggered by a wide range of events, including pull requests, issue comments, and scheduled cron jobs.
The permissions keyword allows you to define granular access controls for GitHub tokens within your workflows. By restricting permissions to the minimum required, you can reduce the risk of accidental or malicious misuse of tokens. For example:
permissions:
contents: read
actions: read
GitHub Actions automatically masks secrets in logs, but you should also avoid printing secrets explicitly in your workflow steps. Use the ::add-mask:: workflow command to mask custom values:
- name: Mask a value
run: echo "::add-mask::$MY_SECRET"
A lockfile (e.g., package-lock.json or pom.lock) records the exact versions of dependencies used in a project. It ensures consistent builds by preventing unexpected updates to dependencies, which could introduce vulnerabilities or breaking changes.
Dependency pinning involves locking third-party actions to specific versions or commit hashes. This prevents automatic updates to potentially compromised versions and reduces the risk of supply chain attacks. Example:
- uses: actions/checkout@a1b2c3d4e5f6g7h8i9j0
An SBOM (Software Bill of Materials) is a detailed inventory of the components and dependencies used in a software project. It provides transparency, enabling organizations to track vulnerabilities and manage risks in their supply chains.
Tools like Syft and Anchore can generate SBOMs for your workflows and dependencies. Example using Syft:
syft ghcr.io/your-repo/your-action:latest -o spdx-json > sbom.json