Your CI/CD Pipeline Is the Easiest Way Into Your Repo (And Nobody's Checking It)
Your CI/CD Pipeline Is the Easiest Way Into Your Repo (And Nobody's Checking It) Your code gets reviewed. Your dependencies get scanned. But your CI/CD pipeline β the thing with access to your secrets, your deployments
Your CI/CD Pipeline Is the Easiest Way Into Your Repo (And Nobody's Checking It)
Your code gets reviewed. Your dependencies get scanned. But your CI/CD pipeline β the thing with access to your secrets, your deployments, and your production credentials β usually gets copy-pasted from a tutorial and never looked at again.
That's the gap plumber-linter was built for.
The problem hiding in plain sight
Here's a workflow file that looks completely normal. It's also a security incident waiting to happen:
name: CI
on: [push]
permissions: write-all
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: some-random-action/setup-node@main
- run: |
echo "Deploying..."
curl -H "Authorization: Bearer AKIAIOSFODNN7EXAMPLE" https://api.example.com/deploy
Three problems, zero warnings from your CI:
-
permissions: write-allβ the workflow can do everything: push code, read secrets, modify releases. A compromised step inherits all of it. -
An unpinned action (
@main) β you're running whatever the maintainer pushes next, sight unseen. If that repo gets hijacked, so does your pipeline. - A hardcoded secret in a run step β it now lives in your git history forever, and anyone with repo access can read it.
Most teams find these during an incident review. plumber-linter finds them before that.
What it checks
plumber-linter scans your CI/CD pipeline configs β GitHub Actions and GitLab CI β and flags:
- Hardcoded secrets in workflow files
-
Overly broad permissions like
write-all - Unpinned third-party actions that can change under you
- Missing branch protections that let unreviewed code straight into main
And instead of cryptic rule IDs, it explains each finding in plain English β what the risk actually is, and how to fix it. So even if you're not a security person, you know exactly what to change and why.
What's new in v1.2.0
The latest release adds 5 new rules, and they cover the stuff I kept seeing in real repos:
-
Unpinned Docker images β
image: node:latestin your workflow means your build changes whenever the image does. Pin it. -
curl | bashβ piping a remote script straight into your shell in CI. If that server is compromised, your runner is too. -
permissions: write-allβ now flagged as its own high-severity rule, not buried in a generic check. - Slack webhooks in plain text β a leaked webhook URL lets anyone post to your channel. It gets flagged the same way a leaked API key does.
-
Unpinned npm packages in CI β
npm install some-package@latestin a pipeline is the same unpinned-action problem, one layer down.
That brings it to 26 rules total. One command, whole pipeline checked.
Try it on your own repo
npm install plumber-linter
plumber .
It takes seconds. If it comes back clean, good β your pipeline is in better shape than most. If it flags something embarrassing, that's the whole point. Fix it, and your next deploy is already safer than your last one.
Why I built it
Pipeline security tools exist, but they're usually heavy, noisy, or written for security teams. I wanted something a regular developer could run in a minute and actually understand the output of. No 200-page report β just the real risks, explained like a person would explain them.
plumber-linter is at v1.2.0 now, with 1,300+ downloads on npm and counting. It's still early, and it's getting better with every release β if you run it on your repo and it catches something, or misses something it should have caught, I'd genuinely love to hear about it.
Try it, break it, and tell me what it missed. Feedback welcome.
π npm: https://www.npmjs.com/package/plumber-linter
π Website: https://plumber-7dv.pages.dev/
π» GitHub: https://github.com/parasraju/plumber
Built for GitHub Actions / GitLab CI. npm install plumber-linter
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.