Antoine Duno
Founder of ZeriFlow · 10 years fullstack engineering · About the author
Key Takeaways
- Your GitHub repository is an attack surface — vulnerable dependencies, hardcoded secrets, and insecure code patterns all live there before they reach production. This guide covers every tool available for GitHub repository security scanning, from built-in features to advanced external tools.
- Includes copy-paste code examples and step-by-step instructions.
- Free automated scan available to verify your implementation.
How to Scan Your GitHub Repository for Security Vulnerabilities
Scanning your GitHub repository for security vulnerabilities is not a once-per-year task. Every dependency you install, every line of code you commit, and every configuration file you push can introduce a new risk. The goal is to make security scanning automatic — so vulnerabilities are caught before they ever reach production.
This guide covers every layer of GitHub repository security scanning: GitHub''s native tools, external specialized scanners, and how to build a scanning pipeline that runs on every push.
Why Repositories Are a Security Target
Most developers think of security as a runtime concern — what happens when the application is running in production. But the repository itself is a target:
- Secrets in code: API keys, database credentials, and private keys committed to git (even briefly) are indexed by bots within minutes
- Vulnerable dependencies: A single line in
package.jsoncan introduce a known CVE affecting millions of users - Insecure patterns: SQL injection sinks, missing authentication middleware, and unsafe deserialization are often visible in static analysis before runtime
- Supply chain attacks: Compromised dependencies in your
package-lock.jsoncan ship malware to production
GitHub provides tools for all of these. The challenge is knowing which tool covers which risk and how to configure them effectively.
GitHub''s Built-In Security Tools
Dependabot
Dependabot monitors your repository''s dependency files and automatically opens pull requests when a new version fixes a known vulnerability.
What it scans:
- package.json / package-lock.json (npm)
- requirements.txt / Pipfile / pyproject.toml (Python)
- Gemfile.lock (Ruby)
- pom.xml / build.gradle (Java)
- go.mod (Go)
- Cargo.lock (Rust)
- composer.lock (PHP)
- GitHub Actions workflow files (.github/workflows/*.yml)
How to enable:
Method 1: Via GitHub UI 1. Go to your repository → Security tab → Enable Dependabot alerts 2. Optionally enable Dependabot security updates (auto-creates PRs)
Method 2: Via .github/dependabot.yml file
# .github/dependabot.yml
version: 2
updates:
# Node.js dependencies
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
assignees:
- "your-github-username"
labels:
- "security"
- "dependencies"
# GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"How to handle Dependabot PRs:
Not every Dependabot PR is safe to merge automatically. Review the PR description — Dependabot explains the CVE and why the version bump is safe. For patch and minor version updates to well-tested packages, auto-merging is reasonable. For major version bumps, review manually.
Enable auto-merge for low-risk updates:
# .github/dependabot.yml
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily"
# Auto-merge patch and minor updates
versioning-strategy: increaseSecret Scanning
GitHub secret scanning checks every push for over 200 patterns corresponding to secrets from major providers: AWS, Stripe, GitHub, Google, Slack, SendGrid, Twilio, and more.
For public repositories: Enabled by default and free.
For private repositories: Requires GitHub Advanced Security (included in GitHub Team and GitHub Enterprise).
How to view alerts:
Repository → Security tab → Secret scanning alerts
Each alert shows: - The secret type (e.g., "Stripe API Key") - The exact commit where it was found - The file and line number - Whether the secret has been validated as active
Push protection: You can also block pushes that contain secrets before they are committed:
Repository → Settings → Security → Secret scanning → Push protection → Enable
With push protection enabled, GitHub blocks the push if it detects a secret pattern. The developer can still override if it is a false positive.
Code Scanning (GitHub Advanced Security / CodeQL)
CodeQL is GitHub''s semantic code analysis engine. Unlike pattern matching, CodeQL understands code flow — it can find vulnerabilities like SQL injection, XSS, and path traversal where user input flows into dangerous sinks across multiple function calls.
For public repositories: Free.
Setup via GitHub Actions:
# .github/workflows/codeql.yml
name: CodeQL Analysis
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
schedule:
- cron: "0 3 * * 1" # Weekly at 3am Monday
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
matrix:
language: [javascript] # Add python, java, etc. as needed
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{ matrix.language }}"View results: Repository → Security tab → Code scanning alerts
External Tools for Deeper Scanning
ZeriFlow Advanced Scan
ZeriFlow accepts a GitHub repository URL or ZIP upload and runs a combined scan covering:
- Hardcoded secrets (API keys, tokens, credentials)
- CVEs in dependencies with exploitability context
- Insecure API patterns (missing auth middleware, open debug endpoints, unsafe HTTP methods)
The combined report gives you a security score and a prioritized fix list. Useful before major releases, security reviews, or when onboarding a legacy codebase.
Snyk
Snyk offers deep dependency and code scanning with a developer-friendly UI:
# Install Snyk CLI
npm install -g snyk
# Authenticate
snyk auth
# Test dependencies for vulnerabilities
snyk test
# Monitor and get notified of new vulnerabilities
snyk monitor
# Test Docker image
snyk container test your-image:latest
# Test infrastructure-as-code
snyk iac test terraform/GitHub integration: Snyk can be added as a GitHub App that comments on pull requests with vulnerability findings.
OSSF Scorecard
The OpenSSF Scorecard evaluates your repository against security best practices across 18 checks:
# Install scorecard
go install sigs.k8s.io/scorecard/v4/cmd/scorecard@latest
# Run against your repository
scorecard --repo github.com/yourorg/yourrepo --show-detailsOr use the GitHub Action:
# .github/workflows/scorecard.yml
name: Scorecard supply-chain security
on:
push:
branches: [main]
schedule:
- cron: "0 3 * * 1"
jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-latest
permissions:
security-events: write
id-token: write
contents: read
actions: read
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Run analysis
uses: ossf/scorecard-action@v2.3.3
with:
results_file: results.sarif
results_format: sarif
publish_results: true
- name: Upload to code-scanning dashboard
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarifBuilding an Automated Scanning Pipeline
A complete GitHub security scanning pipeline runs on every push and pull request:
# .github/workflows/security.yml
name: Security Scan
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
dependency-audit:
name: Dependency Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npm ci
- run: npm audit --audit-level=high
# Fails the build if high or critical vulnerabilities are found
secret-scan:
name: Secret Detection
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for secret scanning
- name: Run truffleHog
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.repository.default_branch }}
head: HEAD
extra_args: --only-verified
sast:
name: Static Analysis (Semgrep)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Semgrep
uses: semgrep/semgrep-action@v1
with:
config: p/security-audit p/owasp-top-tenThis pipeline runs three checks on every pull request:
1. npm audit — blocks PRs with high/critical dependency vulnerabilities
2. truffleHog — blocks PRs that introduce verified secrets
3. Semgrep — reports SAST findings without blocking (adjust fail_open as needed)
What to Look For and How to Prioritize
Prioritization framework
Not all vulnerability findings require immediate action. Use this framework:
Fix immediately (before merge): - Critical CVSS vulnerabilities in packages that directly handle user input or authentication - Any confirmed hardcoded credential - Verified secrets (truffleHog or GitHub secret scanning confirmed the credential is valid)
Fix within one sprint: - High CVSS vulnerabilities in production dependencies - CodeQL findings with high confidence in authentication, authorization, or injection categories
Fix when convenient: - Moderate vulnerabilities in dev dependencies that do not ship to production - Low confidence SAST findings requiring manual review - Vulnerabilities in packages not used in the vulnerable code path
Reducing false positives
npm audit in particular generates many false positives for vulnerabilities in dev-only dependencies. Use --omit=dev to focus on production dependencies:
npm audit --omit=dev --audit-level=highFor Semgrep findings, add # nosemgrep comments to suppress specific false positives after review:
const query = `SELECT * FROM public WHERE id = ''${slug}''`; // nosemgrep: sql-injection
// (Acceptable because ''slug'' is validated by a regex allow-list above)Document your reasoning for suppressed findings.
Monitoring vs Scanning
Scanning finds vulnerabilities at a point in time. Monitoring finds new vulnerabilities in code that was previously safe.
Dependabot handles the dependency monitoring layer automatically — it watches the advisory databases and opens PRs when new CVEs affect packages you are already using.
For web-level security monitoring (new headers dropping, certificate expiry, DNS changes), use ZeriFlow''s monitoring feature for daily or weekly automated scans with email, Slack, or Discord alerts.
Summary
Scanning your GitHub repository for security vulnerabilities should be automatic and continuous, not manual and occasional. Enable Dependabot for dependency vulnerability PRs, secret scanning for credential leak detection, and CodeQL for semantic code analysis. Add truffleHog and Semgrep to your CI pipeline for additional coverage. Use ZeriFlow''s Advanced Scan for a comprehensive pre-release check covering secrets, CVEs, and insecure API patterns together. Prioritize findings by exploitability in your specific context, and document your reasoning when suppressing false positives.
Add security scanning to your CI/CD pipeline.
Catch vulnerabilities before they reach production.