Security Tools Every Developer Should Know
Security Tools Every Developer Should Know
Most developers know they should care about security, but the tooling landscape is overwhelming. There are hundreds of scanners, analyzers, and platforms -- most of them noisy, slow, or both. This guide covers the tools that actually matter and gives you a practical plan for integrating them without drowning in false positives.
The Security Tool Landscape
| Category | Tools | What It Catches |
|---|---|---|
| Dependency scanning | npm audit, Snyk, Socket | Known vulnerabilities in dependencies |
| Secret detection | gitleaks, trufflehog, git-secrets | API keys, tokens, passwords in code |
| SAST | Semgrep, CodeQL | Bugs and vulnerabilities in your code |
| Container scanning | Trivy, Grype | Vulnerabilities in container images |
| Supply chain | lockfile-lint, Scorecard | Integrity of your dependency chain |
Start with dependency scanning and secret detection -- they catch the most common real-world problems with the least effort.
Dependency Scanning
Your dependencies are your largest attack surface. A typical JavaScript project pulls in hundreds of transitive packages, and any one of them could contain a known vulnerability.
npm audit is built in, free, and zero-config. The problem is noise -- it reports vulnerabilities in dev dependencies and transitive packages you can't easily update.
npm audit # check for vulnerabilities
npm audit fix # auto-fix what it can
npm audit --audit-level=high # fail only on high/critical (useful in CI)
Snyk provides better prioritization. It considers whether a vulnerability is actually reachable in your code, which drastically reduces false positives. The free tier covers open source projects.
npm install -g snyk
snyk auth
snyk test # one-time check
snyk monitor # continuous monitoring
Socket takes a fundamentally different approach -- instead of checking a vulnerability database, it analyzes package behavior, looking for network access, filesystem operations, and suspicious install scripts. It catches supply chain attacks that databases miss entirely.
Use npm audit as a baseline. Add Socket for behavioral analysis. Use Snyk if you need prioritized results and are willing to pay. Running npm audit plus Socket gives excellent coverage at minimal cost.
Secret Detection
Leaked secrets are the number one cause of breaches that make developers lose sleep. A single AWS key committed to a public repo can cost thousands in minutes.
gitleaks
Fast, accurate, and sensible defaults. This should be your primary tool.
gitleaks detect # scan current state
gitleaks detect --log-opts="--all" # scan full git history
gitleaks protect --staged # pre-commit hook mode
You can customize detection with .gitleaks.toml -- add custom regex patterns for your own API key formats and allowlist test files to reduce noise.
trufflehog
Goes further than pattern matching -- it verifies whether detected credentials are actually live. The --only-verified flag means near-zero false positives.
trufflehog git file://. --only-verified
trufflehog github --org=mycompany --only-verified
git-secrets
AWS's own tool, focused specifically on preventing AWS credential commits. Run git secrets --install && git secrets --register-aws to set it up. Narrower than gitleaks but useful if AWS is your primary concern.
Pre-commit Integration
The best time to catch a secret is before it enters git history. Add gitleaks to .pre-commit-config.yaml or as a simple git hook (gitleaks protect --staged --verbose in .git/hooks/pre-commit).
Use gitleaks as your primary tool. Add trufflehog for periodic deep scans with verification, especially before open-sourcing a repo.
SAST Tools
SAST tools analyze source code for vulnerabilities and dangerous patterns without running it.
Semgrep
The best SAST tool for most developers. Fast, excellent default rules, and custom rules in readable YAML.
semgrep --config auto . # community rules
semgrep --config p/owasp-top-ten . # specific ruleset
Custom rules are where Semgrep shines:
# .semgrep/custom-rules.yml
rules:
- id: no-raw-sql
patterns:
- pattern: db.query($SQL, ...)
- pattern-not: db.query("...", ...)
message: "Use parameterized queries, not string concatenation"
languages: [typescript, javascript]
severity: ERROR
- id: no-eval
pattern: eval(...)
message: "Never use eval() -- it enables code injection"
languages: [typescript, javascript]
severity: ERROR
CodeQL
GitHub's SAST engine. More powerful than Semgrep for deep dataflow analysis -- it can track user input through your code to see if it reaches a dangerous sink. Slower and harder to run locally, but excellent as a CI check.
# .github/workflows/codeql.yml
name: CodeQL Analysis
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
analyze:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- uses: actions/checkout@v4
- uses: github/codeql-action/init@v3
with:
languages: javascript-typescript
- uses: github/codeql-action/analyze@v3
Use Semgrep for fast local feedback and custom rules. Enable CodeQL on GitHub for deeper analysis. They complement each other -- Semgrep catches common patterns quickly, CodeQL finds complex dataflow issues.
Container Scanning
Container images bundle an entire OS worth of packages. If you ship containers, you need to scan them.
Trivy
The best all-in-one scanner -- handles images, filesystems, git repos, and Kubernetes manifests.
trivy image myapp:latest # basic scan
trivy image --severity HIGH,CRITICAL --exit-code 1 myapp:latest # CI mode
trivy config Dockerfile # scan Dockerfile
trivy fs . # scan filesystem
Grype
Anchore's open-source scanner. Faster than Trivy for pure image scanning, integrates with Syft for SBOM generation.
grype myapp:latest --fail-on high
Use Trivy. It does everything Grype does and more. Grype is a solid alternative if you're already in the Anchore ecosystem.
Supply Chain Security
Supply chain attacks target the tools and processes you use to build software. This is the hardest category to defend against.
Lockfile Auditing
npm ci # fails if lockfile doesn't match package.json
npx lockfile-lint \
--path package-lock.json \
--type npm \
--allowed-hosts npm \
--validate-https # verify all deps resolve over HTTPS
OpenSSF Scorecard
Evaluates the security posture of open source projects before you adopt them.
scorecard --repo=github.com/expressjs/express
Scorecard checks for branch protection, signed releases, dependency pinning, CI tests, and fuzzing. A low score doesn't mean insecure, but it means maintainers haven't adopted security best practices.
Pinning and Reproducibility
Pin CI actions and base images to digests, not tags. Tags are mutable -- a compromised registry can change what they point to.
# Bad: mutable tag
- uses: actions/checkout@v4
# Good: pinned to digest
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
# Bad: mutable tag
FROM node:20-alpine
# Good: pinned to digest
FROM node:20-alpine@sha256:abc123def456...
Renovate and Dependabot can automatically update pinned digests when new versions release.
CI Integration
A practical GitHub Actions workflow combining the most important tools:
# .github/workflows/security.yml
name: Security Checks
on:
pull_request:
push:
branches: [main]
jobs:
secrets:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
dependencies:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm audit --audit-level=high
sast:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: returntocorp/semgrep-action@v1
with:
config: >-
p/typescript
p/owasp-top-ten
container:
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- uses: actions/checkout@v4
- run: docker build -t myapp:${{ github.sha }} .
- uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
severity: HIGH,CRITICAL
exit-code: 1
Each job runs in parallel, keeping feedback fast. Secret detection, dependency scanning, and SAST run on every PR. Container scanning runs on pushes to main.
What to Set Up First
Security tooling is useless if it overwhelms you before it earns your trust. Here's the priority order:
- gitleaks pre-commit hook -- 5 minutes to set up. Prevents the most damaging mistakes.
- npm audit in CI -- Already built in. Add
npm audit --audit-level=highto your pipeline. - Semgrep with default rules -- One command, catches real bugs. Start with
--config auto. - Trivy for containers -- Non-negotiable if you ship containers.
- CodeQL on GitHub -- Enable in repo settings. Zero maintenance.
- Socket for supply chain -- Install the GitHub app. Automatic on PRs.
- Scorecard and lockfile-lint -- Add once the basics are solid.
Don't adopt everything at once. Each tool should be tuned to produce near-zero false positives before you move to the next. A single well-configured scanner is worth more than five noisy ones that everyone ignores.
Recommendations
- Start with secret detection and dependency scanning. They catch the most common problems with the least configuration.
- Run security checks in CI, not just locally. Developers forget to run local tools. CI never forgets.
- Use Semgrep custom rules to enforce your project's specific security patterns. Generic rules are good; project-specific rules are better.
- Pin CI actions and base images to digests. Tags are mutable and trusting them is a supply chain risk.
- Treat security tool output like test failures -- red blocks the merge. Allow overrides only with review from a security-conscious team member.
- Review new dependencies before adding them. Check their Scorecard, look at maintainer count, and read the source of small packages. Five minutes of review prevents weeks of incident response.