Skip to content
Security First — Part 21 of 30

Free Security Scanning Tools You Should Run Today

Written by claude-sonnet-4 · Edited by claude-sonnet-4
securitysastsemgrepbanditeslintnpm-auditpip-audittrivytrufflehoggitleaksowasp-zapsecret-detectiondependency-scanningvibe-codingdevSecOps

Security First — Part 21 of 30


Last September, a security engineer named Luke Marshall ran TruffleHog against 5.6 million public GitLab repositories. In just over 24 hours — at a total cost of $770 in cloud compute — he found 17,430 verified live secrets: Google Cloud credentials, MongoDB keys, OpenAI API tokens, and hundreds of GitLab access keys sitting in plain sight. Many of those secrets were committed by developers who thought they were being careful.

Here's the part that should concern you: most of those repos weren't abandoned hobbyist projects. They were active codebases — the kind that handle real users, real data, and real money.

If you're a vibe coder — someone who builds with AI assistance and ships fast — the odds are good that your codebase has at least one of the issues we've covered in this series: a SQL injection hole, an XSS vector, a hardcoded secret, or a dependency carrying a known CVE. The good news? There are free tools that can find these in minutes. You don't need to be a security expert. You just need to run the right commands.

Let's do it.


Why Automated Scanning Matters Right Now

Before we get into the tools, here's the context that should motivate you to act today:

  • In 2025, 28.65 million new hardcoded secrets were added to public GitHub repositories — a 34% increase over the prior year, according to GitGuardian's 2026 State of Secrets Sprawl report. Repositories using AI coding assistants had a 40% higher secret leakage rate than average.
  • In September 2025, a self-replicating npm worm called Shai-Hulud compromised 18 popular packages — including chalk and debug, with a combined 2.6 billion weekly downloads. It used TruffleHog itself as a payload to scan hosts and exfiltrate developer credentials.
  • According to DeepStrike's 2025 vulnerability statistics, XSS and SQL injection are still among the most commonly reported vulnerability classes in 2025. These are problems that SAST tools catch automatically.

The attack surface is growing. Scanners are fast and free. There's no excuse not to run them.


The Eight Tools

Here's what we're covering, matched to the vulnerabilities from earlier in this series:

Tool What It Catches Language/Platform
Semgrep SQLi, XSS, insecure patterns Any (Python, JS, Go, Java, etc.)
Bandit Python-specific security issues Python
ESLint security plugins XSS, injection in JS/TS JavaScript/TypeScript
npm audit Known CVEs in dependencies Node.js
pip-audit Known CVEs in dependencies Python
Trivy Container vulnerabilities, misconfigs Docker/Kubernetes
TruffleHog / Gitleaks Hardcoded secrets, leaked credentials Any (scans git history)
OWASP ZAP Runtime web vulnerabilities Any web app

Let's go tool by tool.


1. Semgrep — Your First Line of Defense

Semgrep is a static analysis tool that scans your source code for patterns that match known vulnerability signatures. It supports 30+ languages and has a massive free ruleset.

Install and run:

# Install
pip install semgrep

# Run against your project with the default security ruleset
semgrep --config=auto .

# Run only the OWASP Top 10 rules
semgrep --config=p/owasp-top-ten .

# Run Python-specific security rules
semgrep --config=p/python .

What you'll see:

┌─────────────────┐
│ 3 findings │
└─────────────────┘

app/db.py
  python.sqlalchemy.security.sqlalchemy-execute-raw-query.sqlalchemy-execute-raw-query
  Line 42: db.execute(f"SELECT * FROM users WHERE id = {user_id}")
  Severity: ERROR
  Message: Detected string formatting in a possibly vulnerable SQL query.
           Use parameterized queries instead.

That finding? That's the SQL injection bug from Part 7. Semgrep caught it in seconds.

For JavaScript/TypeScript projects, add:

semgrep --config=p/javascript .
semgrep --config=p/typescript .

2. Bandit — Python Security Linting

Bandit was built specifically for Python. It scans your AST (abstract syntax tree) and flags dangerous patterns: eval() calls, hardcoded passwords, use of weak cryptography, shell injection risks.

Install and run:

# Install
pip install bandit

# Scan your project recursively
bandit -r ./myproject

# Get a full report with severity and confidence levels
bandit -r ./myproject -l -i

# Output as JSON for CI integration
bandit -r ./myproject -f json -o bandit-report.json

Example output:

>> Issue: [B608:hardcoded_sql_expressions] Possible SQL injection
   Severity: MEDIUM   Confidence: MEDIUM
   Location: app/routes.py:34
   34  query = "SELECT * FROM orders WHERE user=" + username

>> Issue: [B106:hardcoded_password_funcarg] Possible hardcoded password
   Severity: LOW   Confidence: MEDIUM
   Location: app/config.py:12
   12  connect(password="admin123")

Bandit won't catch everything, but for pure Python projects it's the fastest tool to run and the output is human-readable even if you're not a security professional.


3. ESLint Security Plugin — JavaScript/TypeScript

If your project has any frontend JavaScript or TypeScript, the eslint-plugin-security package adds security-focused linting rules on top of your existing ESLint setup.

Install and configure:

# Install
npm install --save-dev eslint-plugin-security

# Or for TypeScript projects:
npm install --save-dev eslint-plugin-security @typescript-eslint/eslint-plugin

Add to your .eslintrc.js:

module.exports = {
  plugins: ['security'],
  extends: ['plugin:security/recommended'],
  rules: {
    // Catch common injection patterns
    'security/detect-non-literal-regexp': 'warn',
    'security/detect-possible-timing-attacks': 'warn',
    'security/detect-non-literal-fs-filename': 'error',
    'security/detect-child-process': 'error',
  }
};

Run it:

npx eslint . --ext .js,.ts,.tsx

You'll get warnings like:

app/api.js
  Line 23: security/detect-non-literal-regexp  RegExp with user-supplied input
  Line 45: security/detect-child-process        Found child_process import

4. npm audit — Dependency Vulnerability Scanning

npm audit is built into npm. It checks your installed packages against a database of known CVEs. You should be running this before every deployment.

# Run a full audit
npm audit

# Auto-fix compatible vulnerabilities
npm audit fix

# Force-fix (careful: may introduce breaking changes)
npm audit fix --force

# Get JSON output for automation
npm audit --json > npm-audit-report.json

Example output:

found 3 vulnerabilities (1 moderate, 2 high)

high  Prototype Pollution in lodash
      Package: lodash
      Current version: 4.17.11
      Patched in: >=4.17.21
      Run `npm audit fix` to resolve

In 2025, attackers published 454,648 malicious npm packages in a single year, with 99% of all open source malware now targeting the npm ecosystem (Sonatype, 2026). npm audit won't catch intentionally malicious packages, but it catches the known CVEs — and that's a lot of your attack surface.


5. pip-audit — Python Dependency Scanning

The Python equivalent of npm audit. It checks your installed packages against the PyPI Advisory Database and OSV.

# Install
pip install pip-audit

# Audit your current environment
pip-audit

# Audit from a requirements file
pip-audit -r requirements.txt

# Audit with a specific output format
pip-audit --format json -o pip-audit-report.json

# Auto-fix when possible
pip-audit --fix

Example output:

Name       Version  ID                  Fix Versions
---------- -------- ------------------- ------------
requests   2.25.1   GHSA-j8r2-6x86-q33q 2.31.0
jinja2     2.11.3   GHSA-g3rq-g295-4j3m 3.1.3

If you're using a virtual environment (and you should be), run pip-audit inside it so it checks exactly what your app is using.


6. Trivy — Container and Infrastructure Scanning

If you're deploying with Docker, Trivy is essential. It scans container images for OS-level CVEs, application dependency vulnerabilities, exposed secrets, and infrastructure misconfigurations.

Install:

# macOS
brew install aquasecurity/trivy/trivy

# Linux
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin

# Or use Docker
docker pull aquasec/trivy

Run it:

# Scan a Docker image
trivy image myapp:latest

# Scan only HIGH and CRITICAL vulnerabilities
trivy image --severity HIGH,CRITICAL myapp:latest

# Scan your local filesystem
trivy fs .

# Scan and output as SARIF for GitHub Advanced Security
trivy image --format sarif --output trivy-results.sarif myapp:latest

# Scan for secrets in an image
trivy image --scanners secret myapp:latest

Example output:

myapp:latest (ubuntu 22.04)
Total: 5 (HIGH: 3, CRITICAL: 2)

┌──────────────────────┬────────────────┬──────────┬────────────────────┐
│ Library              │ Vulnerability  │ Severity │ Fixed Version      │
├──────────────────────┼────────────────┼──────────┼────────────────────┤
│ openssl              │ CVE-2024-4603  │ HIGH     │ 3.0.14-1ubuntu2    │
│ libexpat1            │ CVE-2024-45492 │ CRITICAL │ 2.5.0-1ubuntu0.1   │
└──────────────────────┴────────────────┴──────────┴────────────────────┘

Trivy is especially powerful for catching vulnerabilities that live in your base image — the Ubuntu or Alpine layer that your app sits on top of — which no application-level scanner will ever see.


7. TruffleHog and Gitleaks — Secret Detection

These two tools scan your git history for secrets: API keys, passwords, tokens, private keys. The critical insight is that they scan your entire commit history — meaning secrets you deleted two years ago are still findable in git.

TruffleHog

# Install
curl -sSfL https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh | sh -s -- -b /usr/local/bin

# Scan your current repository (full history)
trufflehog git file://.

# Scan only verified (confirmed-active) secrets
trufflehog git file://. --only-verified

# Scan a remote GitHub repo
trufflehog github --repo https://github.com/yourname/yourrepo

# Scan since last commit only (good for CI/pre-push hook)
trufflehog git file://. --since-commit HEAD --fail

Gitleaks

Gitleaks has the highest recall rate (88%) in independent benchmarks — meaning it finds the most secrets while TruffleHog specializes in verifying whether found secrets are still live.

# Install
brew install gitleaks  # macOS
# Or download from: https://github.com/gitleaks/gitleaks/releases

# Scan the current repo
gitleaks detect --source .

# Scan with verbose output
gitleaks detect --source . --verbose

# Scan and output report
gitleaks detect --source . --report-format json --report-path gitleaks-report.json

# Pre-commit hook mode (fast, only new changes)
gitleaks protect --staged

Use both: TruffleHog to verify which found secrets are still active; Gitleaks for its broad detection coverage. When Luke Marshall scanned 5.6 million GitLab repositories in 2025, he found that roughly 1 in every 1,060 repos contained valid GCP credentials. That's not a hypothetical risk — it's a statistical certainty at scale.


8. OWASP ZAP — Dynamic Web Application Scanning

All the tools above are static — they analyze your code without running it. OWASP ZAP is different: it's a dynamic scanner that actually attacks your running application to find real exploitable vulnerabilities. Think of it as a safe, automated penetration tester.

Install and run a baseline scan:

# Run via Docker (easiest approach)
docker pull ghcr.io/zaproxy/zaproxy:stable

# Baseline scan against a running app
docker run -t ghcr.io/zaproxy/zaproxy:stable zap-baseline.py \
  -t http://localhost:3000

# Full scan (more thorough, takes longer)
docker run -t ghcr.io/zaproxy/zaproxy:stable zap-full-scan.py \
  -t http://localhost:3000

# Generate HTML report
docker run -v $(pwd):/zap/wrk/:rw \
  -t ghcr.io/zaproxy/zaproxy:stable zap-baseline.py \
  -t http://localhost:3000 \
  -r zap-report.html

ZAP will test for XSS, SQL injection, security headers, CSRF, and dozens of other issues against your actual running app. For vibe coders deploying web apps, run this before any major release.


Putting It All Together: A Pre-Deploy Security Script

Here's a shell script that runs the static analysis tools in sequence. Save it as security-check.sh in your project root:

#!/bin/bash
# security-check.sh — Run before every deployment

set -e
echo "=== Security Scan Starting ==="

# Secret detection (run first — critical if found)
echo "\n[1/5] Scanning for secrets with Gitleaks..."
gitleaks detect --source . --no-banner || { echo "SECRETS FOUND — fix before deploying!"; exit 1; }

# Dependency vulnerabilities
if [ -f "package.json" ]; then
  echo "\n[2/5] Auditing npm dependencies..."
  npm audit --audit-level=high
fi

if [ -f "requirements.txt" ]; then
  echo "\n[2/5] Auditing Python dependencies..."
  pip-audit -r requirements.txt
fi

# SAST scanning
echo "\n[3/5] Running Semgrep SAST..."
semgrep --config=auto . --error

# Python-specific
if [ -f "requirements.txt" ]; then
  echo "\n[4/5] Running Bandit..."
  bandit -r . -l -i --exclude ./tests,./venv
fi

# Container scanning
if [ -f "Dockerfile" ]; then
  echo "\n[5/5] Scanning Docker image with Trivy..."
  trivy image --severity HIGH,CRITICAL --exit-code 1 $(basename $(pwd)):latest
fi

echo "\n=== Security Scan Complete ==="

Make it executable and wire it into your workflow:

chmod +x security-check.sh
./security-check.sh

What These Tools Don't Catch

Be honest about limitations:

  • Business logic flaws — a scanner can't know that your discount code should only be used once
  • Brand-new malicious packagesnpm audit only knows about reported CVEs; September 2025's Shai-Hulud worm was missed by npm audit because it was a fresh supply chain attack, not a known CVE
  • Authentication design errors — a scanner won't tell you your JWT secret is too short or your session expiry is 30 days
  • Configuration drift — production environment variables that were secure at deploy time but rotated without updating the app

Automatic scanners are a floor, not a ceiling. They catch the obvious, repeatable mistakes — and that's enormously valuable.


Action Checklist

Run these today, in order:

  • Run Gitleaks on your repo right now: gitleaks detect --source . --verbose
  • Run npm audit or pip-audit on your dependencies
  • Install Semgrep and run semgrep --config=auto . on your codebase
  • Run Bandit if you have a Python project: bandit -r . -l -i
  • Add ESLint security plugin to your JavaScript/TypeScript project
  • Run Trivy if you're deploying containers: trivy image myapp:latest
  • Run OWASP ZAP baseline scan against your staging environment
  • Save the security-check.sh script to your project and commit it
  • Add a pre-commit hook that runs Gitleaks: gitleaks protect --staged
  • Block deployment if any scanner returns HIGH/CRITICAL findings

Ask The Guild

Community prompt: Which of these tools did you run first, and what did it find? Share your results in the Guild forum — even (especially) if it found something embarrassing. The best learning happens when we're honest about what we missed. Did Semgrep catch a SQL injection? Did Gitleaks find an old API key in your history? Tell us what tool, what it found, and how you fixed it. Your story might save someone else's project.


Tom Hundley is a software architect with 25 years of experience. He has been teaching developers — and now vibe coders — how to build things that last. This is Part 21 of the 30-part Security First series.

Sources: TruffleHog GitLab Scan Research | Snyk State of Secrets 2026 | npm Security Vulnerabilities 2026 | DeepStrike Vulnerability Statistics 2025

Copy A Prompt Next

Start safely

If this article changed how you think about the problem, copy a prompt that turns that judgment into one safe, reviewable next step.

Matching public prompts

6

Keep the task scoped, copy the prompt, then inspect one reviewable diff before the agent continues.

Need the safest first move instead? Open the curated sample prompts before you browse the broader library.

SafetyStart Here — Build Safely With AI

Safe Beginner Loop

Use this before any implementation work when you want the agent to stay scoped, explain itself, and stop after one reviewable change.

Preview
"I want to work in a safe beginner loop.
Please do only this one task: [describe one tiny change].
Before making changes:
1. explain your plan in plain English
2. list the files you expect to change
Security First

Turn this security lesson into a repeatable review habit

This article gives you the judgment call. The security paths give you the vocabulary, checklists, and repetition to catch the next issue before it reaches users.

Best Next Path

Compliance and Professional Security

Guild Member · $29/mo

Translate security advice into PCI, HIPAA, SOC 2, and real audit-facing controls instead of hand-wavy best practices.

15 lessonsIncluded with the full Guild Member library

Need the free route first?

Start with Start Here — Build Safely With AI if you want the workflow and vocabulary before you dive into the deeper path above.

T

About Tom Hundley

Tom Hundley writes for builders who need stronger technical judgment around AI-assisted software work. The Guild turns production experience into public articles, copy-paste prompts, and structured learning paths that help non-software developers supervise AI agents more safely.

Do this next

Leave this article with one concrete move. Copy the matching prompt, or start with the path that teaches the safest next skill in sequence.