Compare commits

...

3 Commits

Author SHA1 Message Date
Tony Loehr e073277d70 Merge branch 'main' into cve-example 2026-02-23 13:47:42 -08:00
Tony Loehr 5a2756d778 Merge branch 'main' into cve-example 2026-02-23 11:39:23 -08:00
Tony Loehr a41753c9a1 docs: add CVE scan sample to navigation, fix accordion labels, clarify --yolo flag 2026-02-23 11:21:41 -08:00
3 changed files with 544 additions and 0 deletions
+535
View File
@@ -0,0 +1,535 @@
---
title: "CVE Vulnerability Scanner"
description: "Automatically scan dependencies for CVEs and get AI-powered security reports using Cline CLI in GitHub Actions."
---
Turn noisy dependency audit output into actionable, prioritized security intelligence. This sample uses Cline CLI in GitHub Actions to scan for CVEs automatically — on every PR, on a weekly schedule, or on-demand — and post clear, prioritized reports with exact fix commands.
<Note>
**New to Cline CLI?** This sample assumes you understand Cline CLI basics and have completed the [Installation Guide](https://docs.cline.bot/cline-cli/installation). Start with the [GitHub RCA sample](./github-issue-rca) if you're looking for something simpler.
</Note>
## What It Does
| Trigger | What happens |
|---------|-------------|
| **PR opened** (dependency files changed) | Scans for CVEs, posts analysis as a PR comment |
| **Weekly schedule** (Monday 9am UTC) | Scans for newly disclosed CVEs, creates a GitHub Issue |
| **Manual trigger** | Scan with custom severity filter and optional auto-fix |
For each vulnerability found, Cline provides:
- **Plain-English impact** — what an attacker could actually do
- **Exploitability assessment** — is this theoretical or actively exploited?
- **Exact fix commands** — copy-paste remediation
- **Auto-fix safety** — which fixes are safe to apply without breaking changes
## Quick Start — Local Usage
Before setting up CI/CD, try it locally:
```bash
# Download the script
curl -O https://raw.githubusercontent.com/cline/cline/main/src/samples/cli/cve-scan/scan-cves.sh
chmod +x scan-cves.sh
# Run it (auto-detects npm/yarn/pnpm/pip)
./scan-cves.sh
```
Or skip the script and pipe directly:
```bash
npm audit --json | cline --yolo "Analyze these CVEs. For each: explain impact, assess exploitability, give exact fix commands. Prioritize by severity."
```
<Tip>
The `--yolo` flag (or `-y` for short) runs Cline in fully autonomous mode — it executes commands without waiting for approval. This is what makes piping and CI/CD workflows possible.
</Tip>
## Prerequisites
- **Cline CLI** installed and authenticated ([Installation Guide](https://docs.cline.bot/cline-cli/installation))
- **GitHub repository** with Actions enabled
- **API provider account** (Anthropic, OpenRouter, etc.) with API key added as a repository secret
## Setup
### 1. Copy the Workflow File
```bash
mkdir -p .github/workflows
curl -o .github/workflows/cline-cve-scan.yml \
https://raw.githubusercontent.com/cline/cline/main/src/samples/cli/cve-scan/cline-cve-scan.yml
```
<Accordion title="Click to view the complete cline-cve-scan.yml workflow">
```yaml
name: Cline CVE Scanner
on:
# Weekly scheduled scan — catches new CVEs in existing dependencies
schedule:
- cron: "0 9 * * 1" # Every Monday at 9am UTC
# PR scan — catch vulnerable dependencies before they merge
pull_request:
types: [opened, synchronize, ready_for_review]
paths:
- "package.json"
- "package-lock.json"
- "yarn.lock"
- "pnpm-lock.yaml"
- "requirements.txt"
- "Pipfile.lock"
- "pyproject.toml"
# Manual trigger with options
workflow_dispatch:
inputs:
severity:
description: "Minimum severity to report"
required: false
default: "all"
type: choice
options:
- all
- low
- medium
- high
- critical
auto_fix:
description: "Attempt safe auto-fixes"
required: false
default: false
type: boolean
concurrency:
group: cve-scan-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
cve-scan:
if: |
(github.event_name == 'pull_request' && github.event.pull_request.draft == false) ||
github.event_name == 'schedule' ||
github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
pull-requests: write
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Install Cline CLI
run: npm install -g cline
- name: Configure Cline Authentication
run: |
cline auth --provider anthropic \
--apikey "${{ secrets.ANTHROPIC_API_KEY }}" \
--modelid claude-sonnet-4-5-20250929
- name: Determine scan parameters
id: params
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
echo "severity=${{ inputs.severity }}" >> $GITHUB_OUTPUT
echo "auto_fix=${{ inputs.auto_fix }}" >> $GITHUB_OUTPUT
elif [ "${{ github.event_name }}" == "pull_request" ]; then
echo "severity=high" >> $GITHUB_OUTPUT
echo "auto_fix=false" >> $GITHUB_OUTPUT
else
echo "severity=all" >> $GITHUB_OUTPUT
echo "auto_fix=false" >> $GITHUB_OUTPUT
fi
if [ "${{ github.event_name }}" == "pull_request" ]; then
echo "output=pr-comment" >> $GITHUB_OUTPUT
echo "pr_number=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
else
echo "output=github-issue" >> $GITHUB_OUTPUT
echo "pr_number=" >> $GITHUB_OUTPUT
fi
- name: Download CVE scan script
run: |
curl -sL https://raw.githubusercontent.com/${{ github.repository }}/main/scan-cves.sh -o scan-cves.sh \
|| cp src/samples/cli/cve-scan/scan-cves.sh scan-cves.sh 2>/dev/null \
|| true
chmod +x scan-cves.sh
- name: Run CVE scan with Cline
env:
GH_TOKEN: ${{ github.token }}
GITHUB_REPOSITORY: ${{ github.repository }}
CLINE_COMMAND_PERMISSIONS: |
{
"allow": [
"npm audit *",
"yarn audit *",
"pnpm audit *",
"pip-audit *",
"gh issue create *",
"gh issue list *",
"gh pr comment *",
"cat *",
"echo *"
],
"deny": [
"rm *",
"sudo *",
"npm install *",
"npm publish *"
]
}
run: |
PR_FLAG=""
if [ -n "${{ steps.params.outputs.pr_number }}" ]; then
PR_FLAG="--pr ${{ steps.params.outputs.pr_number }}"
fi
AUTO_FIX_FLAG=""
if [ "${{ steps.params.outputs.auto_fix }}" == "true" ]; then
AUTO_FIX_FLAG="--auto-fix"
fi
./scan-cves.sh \
--scanner npm \
--output ${{ steps.params.outputs.output }} \
--severity ${{ steps.params.outputs.severity }} \
$PR_FLAG \
$AUTO_FIX_FLAG
```
</Accordion>
### 2. Add the Scan Script
Add `scan-cves.sh` to your repository root (or wherever the workflow downloads it from):
```bash
curl -O https://raw.githubusercontent.com/cline/cline/main/src/samples/cli/cve-scan/scan-cves.sh
chmod +x scan-cves.sh
```
<Accordion title="Click to view scan-cves.sh (simplified — see source for full version)">
```bash
#!/bin/bash
# scan-cves.sh — CVE vulnerability scanner powered by Cline CLI
#
# Usage:
# ./scan-cves.sh # Auto-detect scanner, stdout
# ./scan-cves.sh --output github-issue # Post as GitHub Issue
# ./scan-cves.sh --output pr-comment --pr 42 # Post as PR comment
# ./scan-cves.sh --scanner npm --severity critical # Filter by severity
# cat audit.json | ./scan-cves.sh --scanner custom # Custom scanner input
set -euo pipefail
SCANNER=""
OUTPUT="stdout"
SEVERITY="all"
PR_NUMBER=""
REPO="${GITHUB_REPOSITORY:-}"
AUTO_FIX="false"
CLINE_EXTRA_FLAGS=""
while [[ $# -gt 0 ]]; do
case "$1" in
--scanner) SCANNER="$2"; shift 2 ;;
--output) OUTPUT="$2"; shift 2 ;;
--severity) SEVERITY="$2"; shift 2 ;;
--pr) PR_NUMBER="$2"; shift 2 ;;
--repo) REPO="$2"; shift 2 ;;
--auto-fix) AUTO_FIX="true"; shift ;;
--config) CLINE_EXTRA_FLAGS="$CLINE_EXTRA_FLAGS --config $2"; shift 2 ;;
--model) CLINE_EXTRA_FLAGS="$CLINE_EXTRA_FLAGS -m $2"; shift 2 ;;
-h|--help) echo "Usage: scan-cves.sh [--scanner npm|yarn|pnpm|pip|custom] [--output stdout|github-issue|pr-comment|file] [--severity all|critical|high|medium|low] [--pr N] [--repo owner/repo] [--auto-fix] [--config path] [--model id]"; exit 0 ;;
*) echo "Unknown option: $1"; exit 1 ;;
esac
done
# Auto-detect scanner from lockfiles
if [[ -z "$SCANNER" ]]; then
if [[ -f "package-lock.json" ]]; then SCANNER="npm"
elif [[ -f "yarn.lock" ]]; then SCANNER="yarn"
elif [[ -f "pnpm-lock.yaml" ]]; then SCANNER="pnpm"
elif [[ -f "requirements.txt" ]] || [[ -f "Pipfile.lock" ]]; then SCANNER="pip"
else echo "Error: Could not detect package manager." >&2; exit 1; fi
echo "Auto-detected scanner: $SCANNER" >&2
fi
# Run the scan
case "$SCANNER" in
npm) SCAN_OUTPUT=$(npm audit --json 2>/dev/null || true) ;;
yarn) SCAN_OUTPUT=$(yarn audit --json 2>/dev/null || true) ;;
pnpm) SCAN_OUTPUT=$(pnpm audit --json 2>/dev/null || true) ;;
pip) SCAN_OUTPUT=$(pip-audit --format json 2>/dev/null || true) ;;
custom) SCAN_OUTPUT=$(cat) ;;
*) echo "Unknown scanner: $SCANNER" >&2; exit 1 ;;
esac
if [[ -z "$SCAN_OUTPUT" ]]; then echo "✅ No vulnerabilities found!" >&2; exit 0; fi
# Build the security analyst prompt
PROMPT='You are a senior security analyst. Analyze these vulnerability scan results.
For EACH vulnerability: provide CVE ID, severity, affected package with versions,
plain-English impact, exploitability assessment, exact fix commands, and auto-fix safety.
Format as markdown with sections: 🔴 Critical, 🟠 High, 🟡 Medium, 🔵 Low,
Summary & Recommended Actions, Risk Assessment.
Omit empty severity sections. Flag actively exploited CVEs with ⚠️.'
if [[ "$SEVERITY" != "all" ]]; then
PROMPT="$PROMPT Focus ONLY on $SEVERITY severity or higher."
fi
# Run Cline analysis
echo "Analyzing vulnerabilities with Cline..." >&2
REPORT=$(echo "$SCAN_OUTPUT" | cline -y $CLINE_EXTRA_FLAGS "$PROMPT" 2>/dev/null)
# Output results
case "$OUTPUT" in
stdout) echo "$REPORT" ;;
github-issue) gh issue create --repo "$REPO" --title "🔒 CVE Report — $(date +%Y-%m-%d)" --body "$REPORT" --label "security,automated" ;;
pr-comment) gh pr comment "$PR_NUMBER" --repo "$REPO" --body "$REPORT" ;;
file) echo "$REPORT" > "cve-report-$(date +%Y%m%d-%H%M%S).md" ;;
esac
```
The [full source script](https://github.com/cline/cline/blob/main/src/samples/cli/cve-scan/scan-cves.sh) includes additional features: a `--help` usage guide, `detect_scanner()` and `run_scan()` helper functions, a detailed heredoc security prompt with auto-fix instructions, and JSON output extraction via `jq`.
</Accordion>
### 3. Configure Secrets
1. Go to your repository **Settings** → **Secrets and variables** → **Actions**
2. Add a **New repository secret**:
- **Name:** `ANTHROPIC_API_KEY` (or match the provider in your workflow)
- **Value:** Your API key
### 4. Commit and Push
```bash
git add .github/workflows/cline-cve-scan.yml scan-cves.sh
git commit -m "Add Cline CVE scanner workflow"
git push
```
## Usage
### Automatic Triggers
Once set up, the scanner runs automatically:
- **Weekly (Monday 9am UTC):** Creates a GitHub Issue with a full vulnerability report
- **On PR:** Posts a comment on PRs that modify dependency files (only high+ severity)
### Manual Trigger
Go to **Actions** → **Cline CVE Scanner** → **Run workflow** to trigger a scan with custom options:
- Choose minimum severity level
- Optionally enable auto-fix for safe updates
### Local Usage
```bash
# Basic scan (auto-detects package manager)
./scan-cves.sh
# Save to file
./scan-cves.sh --output file
# Only critical CVEs
./scan-cves.sh --severity critical
# Post as GitHub Issue
./scan-cves.sh --output github-issue --repo myorg/myrepo
# Use a specific model
./scan-cves.sh --model claude-opus-4-5-20251101
# Pipe from any scanner (Trivy, Snyk, Grype, etc.)
trivy fs --format json . | ./scan-cves.sh --scanner custom
```
## How It Works
### Architecture
The scanner follows a three-layer design that keeps each concern separate and extensible:
```
┌─────────────────────────────────────────────────┐
│ Layer 1: Scanner Adapter (pluggable) │
│ npm audit | yarn audit | pip-audit | custom │
└────────────────────┬────────────────────────────┘
│ JSON vulnerability data
┌────────────────────▼────────────────────────────┐
│ Layer 2: Cline Security Analyst (reusable) │
│ AI-powered analysis via cline --yolo │
└────────────────────┬────────────────────────────┘
│ Markdown report
┌────────────────────▼────────────────────────────┐
│ Layer 3: Output Adapter (pluggable) │
│ stdout | GitHub Issue | PR comment | file │
└─────────────────────────────────────────────────┘
```
**Layer 1 (Scanner)** runs the appropriate audit command and produces JSON. You can swap scanners without touching the analysis logic.
**Layer 2 (Cline)** receives the raw vulnerability JSON and produces a prioritized, human-readable report. The security analyst prompt is self-contained and could be extracted into a Prompts Library entry.
**Layer 3 (Output)** delivers the report to its destination. Adding a new output target (e.g., Slack webhook) requires only a few lines in the output case statement.
### The Security Analyst Prompt
The core prompt instructs Cline to act as a senior security analyst. For each CVE, it provides:
1. **CVE ID & Severity** with color-coded sections
2. **Impact Assessment** in plain English (not just "RCE" — the actual attack vector)
3. **Exploitability** — is this a real-world risk or theoretical?
4. **Exact Fix** — copy-paste commands specific to your package manager
5. **Auto-fix Safety** — whether a simple version bump is safe
This prompt is **reusable** — it works with any JSON vulnerability data, not just npm audit. It could be published to the Cline Prompts Library for broader use.
### Security: Command Permissions
The workflow uses `CLINE_COMMAND_PERMISSIONS` to restrict Cline to safe, read-only operations:
```json
{
"allow": ["npm audit *", "gh issue create *", "gh pr comment *"],
"deny": ["rm *", "sudo *", "npm install *", "npm publish *"]
}
```
This ensures Cline can scan and report, but cannot modify your codebase or install packages — even in YOLO mode.
## Customization
### Different Package Managers
The script auto-detects from lockfiles, or you can specify explicitly:
```bash
./scan-cves.sh --scanner yarn
./scan-cves.sh --scanner pnpm
./scan-cves.sh --scanner pip
```
### Model Orchestration
Combine with [Model Orchestration](./model-orchestration) patterns for cost optimization:
```bash
# Cheap model for weekly triage
./scan-cves.sh --config ~/.cline-haiku --severity all
# Expensive model only for critical CVEs
./scan-cves.sh --config ~/.cline-opus --severity critical
```
### Custom Scanners
Pipe output from any scanner that produces JSON:
```bash
# Trivy (container/filesystem scanner)
trivy fs --format json . | ./scan-cves.sh --scanner custom
# Snyk
snyk test --json | ./scan-cves.sh --scanner custom
# Grype
grype dir:. -o json | ./scan-cves.sh --scanner custom
```
### Slack Notifications
Extend the output adapter by piping stdout to a Slack webhook:
```bash
REPORT=$(./scan-cves.sh)
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\": \"$REPORT\"}" \
"$SLACK_WEBHOOK_URL"
```
## Sample Output
Here's an example of a Cline-generated CVE report:
```markdown
# 🔒 CVE Vulnerability Report
**Scan Date:** 2026-02-11
**Scanner:** npm
**Total Vulnerabilities:** 4
## 🔴 Critical Vulnerabilities (1)
### CVE-2022-24999: qs
- **Severity:** Critical
- **Package:** `qs@6.7.0` → fix in `qs@6.11.0`
- **Impact:** Prototype pollution via crafted query strings. An attacker can inject
properties into Object.prototype, which in Express.js apps can lead to remote code
execution or denial of service.
- **Exploitability:** ⚠️ ACTIVELY EXPLOITED — public exploits available, any Express
app using query parsing is vulnerable.
- **Fix:** `npm install qs@6.11.0`
- **Auto-fix safe:** Yes
## 🟠 High Vulnerabilities (2)
### CVE-2023-28155: jsonwebtoken
- **Severity:** High
- **Package:** `jsonwebtoken@8.5.1` → fix in `jsonwebtoken@9.0.0`
- **Impact:** Insecure default algorithm allows an attacker to forge tokens if the
server doesn't explicitly set the algorithm. Could lead to authentication bypass.
- **Exploitability:** Medium — requires the server to not specify algorithms explicitly.
- **Fix:** `npm install jsonwebtoken@9.0.0`
- **Auto-fix safe:** No (major version bump, verify API compatibility)
### CVE-2023-45857: axios
- **Severity:** High
- **Package:** `axios@0.21.1` → fix in `axios@1.6.0`
- **Impact:** SSRF vulnerability allows specially crafted requests to access internal
services. An attacker controlling request URLs could probe internal infrastructure.
- **Exploitability:** Medium — requires user-controlled URL input.
- **Fix:** `npm install axios@1.6.0`
- **Auto-fix safe:** No (major version bump)
## 📋 Summary & Recommended Actions
1. **Immediate:** Update qs to 6.11.0 — critical, actively exploited, safe auto-fix
2. **This sprint:** Update jsonwebtoken to 9.0.0 and axios to 1.6.0 (test for breaking changes)
3. **Safe auto-fix command:** `npm audit fix`
## 📊 Risk Assessment
This project has 1 critical and 2 high severity vulnerabilities. The critical qs
vulnerability is actively exploited and should be fixed immediately — it's a safe
auto-fix with no breaking changes. The jsonwebtoken and axios updates are major
version bumps that require testing but should be scheduled for the current sprint.
Overall dependency hygiene needs improvement — consider running automated CVE scans
weekly to catch issues earlier.
```
## Related Samples
- **[GitHub PR Review](./github-pr-review)** — Automated code review on PRs
- **[GitHub Integration](./github-integration)** — Respond to issues with @cline
- **[Model Orchestration](./model-orchestration)** — Multi-model workflows for cost optimization
+8
View File
@@ -47,6 +47,14 @@ This section provides sample implementations that demonstrate various Cline CLI
>
Automatically review Pull Requests with AI. Configures Cline in GitHub Actions to analyze diffs, check for security issues, and post detailed reviews with inline code suggestions.
</Card>
<Card
title="CVE Vulnerability Scanner (Actions)"
icon="shield-halved"
href="/cline-cli/samples/cve-scan"
>
Automatically scan dependencies for CVEs and get AI-powered security reports. Runs on PRs, weekly schedules, or on-demand. Supports npm, yarn, pnpm, pip, and custom scanners like Trivy and Snyk.
</Card>
</CardGroup>
## Additional Resources
+1
View File
@@ -110,6 +110,7 @@
"cline-cli/samples/github-issue-rca",
"cline-cli/samples/github-integration",
"cline-cli/samples/github-pr-review",
"cline-cli/samples/cve-scan",
"cline-cli/samples/model-orchestration",
"cline-cli/samples/worktree-workflows"
]