关于 Scout Security
Scout 是面向开发者的本地静态安全扫描器,可检查代码、依赖和 Git 历史中的常见问题。它以确定性规则运行,不需要 API 密钥或令牌,并可将结果用于 CI、提交钩子或 AI 修复提示。
主要功能
- 01检测密钥泄露与注入问题
- 02检查安全响应头和依赖漏洞
- 03支持 taint 分析与自定义规则
- 04生成 Markdown、JSON 和 SARIF 报告
- 05通过基线与严重级别控制 CI
适用场景
- 01在提交前扫描代码变更
- 02在 CI 中阻止高严重度问题
- 03为现有项目建立安全基线
- 04扫描 Git 历史中的泄露密钥
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Scout
命令行中的 AI 安全团队。 在黑客之前发现漏洞——免费、本地运行、无需注册。
为什么选择 Scout?
AI 编码助手经常编写不安全的代码——硬编码密钥、SQL 注入、缺少身份验证。独立开发者没有安全团队,只能将这些代码发布出去。
Scout 就是这样的团队。 静态分析能捕获 AI 助手最常犯的错误——密钥泄露、通过字符串拼接构造 SQL、shell=True、缺少安全标头。无需 API 密钥、无需配置、无需付费。
安装
无需安装——使用 uv 一条命令即可试用(无需虚拟环境,冷启动约 1 秒):
uvx scout-security scan ./my-project
或永久安装:
pip install scout-security
也在使用 NCC ScoutSuite? 它也会安装
scout命令,最后安装的包会占用该命令名。Scout 还会安装scoutsec——同一工具,不会发生名称冲突:scoutsec scan ./my-project。
使用方法
# Scan a project — deterministic static analysis: no API keys, no tokens, no signup
scout scan ./my-project
# Turn the findings into ready-to-paste fix prompts for your AI assistant
scout scan ./my-project --format ai-prompt
输出格式
一次扫描,四种视图——使用 --format(-f)选择:
# Layer 1 — human-readable Markdown report (default)
scout scan ./my-app
scout scan ./my-app -o security-report.md
# Layer 2 — ready-to-paste prompts for your own AI (Cursor, Claude, Copilot…)
scout scan ./my-app --format ai-prompt # writes security-prompts.md
scout scan ./my-app --format ai-prompt -o prompts.md
# Layer 3 — machine-readable JSON for piping into agentic tooling / CI
scout scan ./my-app --format json # prints JSON to stdout
scout scan ./my-app --format json -o report.json
scout scan ./my-app --format json | jq '.findings[]'
# Layer 4 — SARIF 2.1.0 for GitHub Code Scanning (PR annotations)
scout scan ./my-app --format sarif -o scout.sarif
它们都由同一引擎驱动——Scout 发现问题;由你自己的 AI(它已经了解你的代码库)来应用修复。
用作 CI 门禁
如果存在严重级别达到或高于 --fail-on(默认值:high)的问题,scout scan 会以 1 退出,因此你的流水线会因实际问题而失败:
scout scan . --fail-on high # default — fail on HIGH or CRITICAL findings
scout scan . --fail-on critical # fail only on CRITICAL
scout scan . --fail-on never # report-only mode — always exit 0
GitHub Action 会封装安装、扫描和 SARIF 上传,因此问题会通过 GitHub Code Scanning 显示为 PR 注释:
jobs:
scout:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v4
- uses: Varpost/[email protected]
with:
fail-on: high # also: path, format, upload-sarif
更喜欢使用普通步骤?手动执行相同操作(该任务仍需 security-events: write):
- run: |
pip install scout-security
scout scan . --no-ai --format sarif -o scout.sarif --fail-on never
- uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: scout.sarif
Pre-commit 钩子
在问题被提交前就将其捕获:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/Varpost/Scout
rev: v0.1.16 # use the latest tag
hooks:
- id: scout
该钩子会在每次提交时从仓库根目录运行 scout scan . --no-ai --fail-on high,因此你的 [tool.scout] 配置会生效。使用 args: ["--fail-on", "critical"] 调整阈值。运行失败时,Scout 会写入包含详情的 security-report.md——建议将它加入 .gitignore。
忽略问题
在标记行末尾添加注释,即可忽略误报:
result = eval(trusted_expression) # scout: ignore
result = eval(trusted_expression) # scout: ignore[injection]
单独使用 scout: ignore 会忽略该行上的所有问题。指定范围的写法只会忽略指定的扫描器(secrets、injection、headers、deps、custom)或问题 ID(例如 injection/eval_usage——即 --format json 中的 id 字段)。无法添加行内注释的问题——应用级 CSRF 检查没有有意义的行号,而锁文件问题存在于生成的 JSON 中——可以通过 [tool.scout] scanners 关闭扫描器(见下文),或将其加入基线(见下文)来处理。
配置
使用 --exclude 跳过路径(可重复指定;相对于扫描根目录,支持 glob):
scout scan . --exclude tests/fixtures --exclude "*.min.js"
或者在 pyproject.toml 中设置项目默认值——Scout 会从被扫描的项目读取 [tool.scout]:
[tool.scout]
exclude = ["tests/fixtures", "vendor"] # paths or glob patterns to skip
scanners = ["secrets", "injection"] # run a subset: secrets, injection, headers, deps, custom
engines = ["semgrep"] # external engines to run and merge (optional)
rules = ["scout-rules.yml"] # your own YAML detection rules (optional)
fail_on = "medium" # default threshold for --fail-on
命令行标志优先级更高:--exclude 会替换配置列表,--engine 会替换 engines,而 --fail-on 会覆盖 fail_on。
自定义规则(可选)
通过 YAML 文件教 Scout 识别项目专属模式——包含 ID、正则表达式、消息和严重级别:
# scout-rules.yml — referenced from [tool.scout] rules
rules:
- id: internal-api-host
pattern: "internal\\.corp\\.example"
message: "Internal hostname committed to source."
severity: HIGH # CRITICAL | HIGH | MEDIUM | LOW
fix_phase: 1 # optional, 1-5 (default 3)
suffixes: [".py", ".ts"] # optional — default: every scanned file
fix: "Move the hostname to configuration."
这些规则有意设计为带元数据的 grep——需要元变量或污点分析?这正是 --engine semgrep 的用途。格式错误的规则会在 stderr 输出警告并跳过;它绝不会导致扫描失败。自定义问题与原生问题一样,可使用所有功能:scout: ignore[custom]、基线、严重级别门禁、JSON/SARIF。
外部引擎(可选)
Scout 可以协调工业级开源软件引擎,并将它们的发现结果合并到报告、JSON 和 SARIF 输出中 — 使用相同的分阶段修复计划,覆盖范围更广:
pip install semgrep # or brew install semgrep
scout scan . --engine semgrep # native scanners + semgrep, merged & deduped
# CodeQL — GitHub's semantic analysis engine (CLI from
# https://github.com/github/codeql-cli-binaries, on PATH as `codeql`)
scout scan . --engine codeql # builds a CodeQL DB per language (python/js),
# runs the official security queries, merges the SARIF
--engine codeql 会运行 GitHub 代码扫描所使用的同一套查询,因此 Scout 报告可以包含完整的语义分析发现结果 — 预计耗时是几分钟,而不是几秒(数据库提取是 CodeQL 的设计所致,并非 Scout 的额外开销)。
引擎必须由用户显式启用:默认扫描零依赖且完全确定。请求使用但未安装的引擎会被跳过,并显示一行提示 — 绝不会导致崩溃。若引擎发现结果落在原生扫描器已标记的行上,则会将其丢弃,优先保留 Scout 自己的修复建议。
VS Code 扩展
scout-vscode/ 将 CLI 封装为 VS Code 扩展:保存 Python/JS/TS 文件时,只扫描该文件(亚秒级),并将发现结果显示为行内波浪线;经污点追踪的结果会标记为可从用户输入触达。Scout: Scan Workspace 命令会将整个项目的扫描结果填入“问题”面板。它会调用 scoutsec,因此你的 [tool.scout] 配置可以原样使用。
在现有代码库中采用 Scout(基线)
不想在启用 CI 门禁前先修复多年来积累的所有发现结果?先接受当前状态,然后只对新发现结果报错:
scout scan . --write-baseline # accept current findings → .scout-baseline.json
scout scan . --baseline .scout-baseline.json # report and fail only on NEW findings
提交 .scout-baseline.json。发现结果的身份基于内容 — 规则、文件以及被标记行的哈希,刻意不包含行号 — 因此,即使无关编辑导致发现结果在文件中上下移动,已纳入基线的发现结果仍会被接受。修改被标记的行本身,则会使该发现结果重新出现以供审查。
扫描 Git 历史中的机密信息
已提交后又删除的机密信息仍然已经泄露 — 扫描当前代码无法发现它:
scout scan . --git-history # secrets in every added line of every commit, all branches
发现结果会关联到引入它的提交(config.py @ 1a2b3c4d5e6f)— 请轮换它报告的所有凭据;删除该行并不能消除凭据泄露。需要在 PATH 中找到 git;扫描的是历史记录,而不是工作树。
坦诚说明适用范围:Gitleaks 和 TruffleHog 专门用于深度、快速地审计历史记录 — Scout 的扫描是内置的便捷功能,并非替代品。
检测内容
| 扫描器 | 检测内容 | 严重性 |
|---|---|---|
secrets | AWS/Google 密钥、GitHub/GitLab 令牌、Anthropic 和 OpenAI 密钥、Slack/npm/PyPI 令牌、Stripe 密钥、数据库 URL、私钥、密码 | CRITICAL |
injection | SQL 注入、NoSQL 运算符注入、命令注入、eval()/Function/vm、XSS | CRITICAL |
injection(污点门控) | 路径遍历(文件读取/写入、sendFile)、SSRF(fetch/requests/axios)、不安全的反序列化(pickle/yaml.load/unserialize)、开放重定向(redirect(...))— 仅当用户输入到达接收点时才会触发 | HIGH |
injection(关键词门控) | 用于令牌/机密信息的弱随机数(将 Math.random/random.* 用于令牌/密码/OTP) | MEDIUM |
headers | 缺少安全标头(Express/Flask/Django/FastAPI)、通配符 CORS、缺少 CSRF 防护 | LOW–MEDIUM |
deps | pip 和 npm 依赖项中的已知漏洞(通过 OSV.dev) | HIGH |
语言范围
深度分析——注入(SQL/命令/XSS)和安全标头——针对 Python 和 JS/TS,因为检测模式因语言惯用写法而异。两种语言都支持文件内污点追踪(Python 使用标准库 AST,JS/TS 使用词法扫描):当污点源追溯到用户输入(request.*、req.body、location.hash 等)时,检测结果会带有 reachable 判定;ORM/NoSQL 接收点仅在有污点证据时触发;如果 XSS 接收点的输入可证实为文件内常量,则会丢弃该结果,而非报告。同一套污点引擎还用于检测路径遍历(open/fs.readFile/sendFile)、SSRF(requests/fetch/axios)、不安全反序列化(pickle/yaml.load/unserialize)和开放重定向(redirect(...))——这些检测都以可达性为条件,因此 open("config.json") 和 axios.get("https://api.example.com") 永远不会触发。针对令牌/密钥的弱随机数(Math.random/random.*)则通过关键词筛选:仅当名称同时包含令牌、密码或 OTP 时才会标记。密钥检测与语言无关:它会扫描 Scout 收集的所有常见源代码和配置文件(Go、Java、Ruby、PHP、C/C++、Rust、shell、.env、Dockerfile、docker-compose、Terraform 等),因此无论密钥从哪种语言的文件中泄露,都会被检测到。依赖项扫描涵盖 requirements.txt 和 package-lock.json。
实测准确率
Scout 的注入扫描器使用 OpenSSF CVE Benchmark 中的 104 个真实 CVE 进行评估——这些是在真实 JS/TS 项目中的真实易受攻击提交,不含合成测试用例。完整的方法、注意事项和复现步骤见 benchmarks/;结果按版本记录,每次发布时,README 只引用已提交结果文件中的数据。
客观解读 v0.1.16 的结果:总体召回率为 27.4%,精确率为 3.2%——两项指标都较上一版本提升(v0.1.9 为 16.5% / 1.3%)。命令注入表现最突出,召回率达到 41.7%,如今略高于 CodeQL 在该语料库上公布的 40%;这一结果来自对 child_process.exec(cmd, callback) 成员调用的识别,包括使用 [a, b].join(' ') 构建的命令(这是 v0.1.16 的正则正确性修复,同时也避免了误报 regexp.exec(),因此召回率和精确率同步提升);通过 JS 污点分析,SQL/NoSQL 注入保持在 25%(与 CodeQL 持平)。跳过压缩/打包文件也提升了精确率——生成包中的漏洞属于依赖扫描器的工作。添加 --engine semgrep 可进一步提升总体召回率(见 semgrep 结果)。按照基准测试约定,误报数量是上限——每个未标记的真实 exec()/汇点调用都会计入 Scout 的误报。这些数据的发布是为了促进公平比较,并在每次发布中持续改进,而非博人眼球。有关这些数据与 CodeQL、ESLint 以及针对同一语料库发布的研究结果之间的对比,请参阅 benchmarks/COMPARISON.md。
路径遍历 + SSRF(v0.1.12)以及反序列化 + 开放重定向 + 弱随机数(v0.1.13)检测器新增了几类漏洞(CWE-22/918/502/601/330)。这些检测器不会改变上述注入数据(已验证:TP/FP/FN 完全一致)。这些类别使用新增的 39 个 CVE 单独评分。路径遍历的召回率从 0% 的基线(v0.1.13)提升至 46.9%(v0.1.14),这得益于两项基于基本原理的扩展——将请求 URL/路径(req.url)加入污点源,并将 fs.stat/access/exists 加入文件路径汇点;如今其表现甚至超过了该类别的 semgrep 扫描。SSRF、开放重定向和反序列化的召回率仍如实保持在 0%:分析相关 CVE 的数据流后发现,瓶颈在于无法识别的汇点/来源(例如 res.setHeader('Location', …) 重定向、裸用 request({uri}) 客户端)以及对象字面量中的污点传播,而非函数边界;针对这 11 个 CVE 的长尾问题扩大检测范围,带来的误报风险可能得不偿失。请参阅 benchmarks/COMPARISON.md。
v0.1.15 新增 Python 跨函数污点跟踪(文件内):传入本地辅助函数的污点参数现在会使该函数的对应形参也被标记为污点,因此,经过路由处理函数流入服务函数中 os.system 的 request.args 值也能被跟踪到汇点。这对分层 Python 应用有实际价值,而仅包含 JS 的 OpenSSF 语料库无法衡量这一点——与弱随机数检测类似,其效果由单元测试验证,而非基准测试数据。
示例输出
$ scout scan ./my-app
Scout v0.1.16 scanning: ./my-app
Scanning 47 files...
Found 6 issues:
🔴 2 critical
🟠 3 high
🟡 1 medium
Report written to: ./my-app/security-report.md
报告包括:
- 用通俗易懂的语言解释每个漏洞
- 附带背景说明的严重性评级(说明其危险性)
- 每个问题的精确修复说明
- 分阶段的修复计划(优先处理零风险修复)
可选:AI 确认环节
核心扫描始终是静态、确定性、离线且零 Token 的——相同的扫描会得到相同的发现,无需 API 密钥。 这是默认设置,且始终不变。
如果你想进一步过滤误报,Scout 可以选择将每个启发式发现中仅被标记的代码片段(绝不会发送整个文件)发送给 AI 提供商,由其降低严重性,或将其判定为误报。依赖项(OSV)和项目级发现都是确定性事实,绝不会被重新评估。任何提供商错误都不会影响发现结果——该环节会以开放失败方式处理,因此绝不会掩盖真实问题。
默认情况下关闭。按次运行启用:
# Anthropic (needs ANTHROPIC_API_KEY) — uses the cheap Haiku tier by default
scout scan . --model anthropic
# OpenAI (needs OPENAI_API_KEY)
scout scan . --model openai
# Local Ollama (no key, no cloud) — nothing leaves your machine
scout scan . --model ollama --ollama-model llama3
提供商的选择顺序为 --model > SCOUT_AI_PROVIDER 环境变量 > none。使用 SCOUT_AI_MODEL 为每个提供商指定模型。无论配置如何,--no-ai 都会强制关闭该环节。使用 pip install "scout-security[ai]" 安装 SDK(Ollama 无需额外安装)。
MCP 服务(Agent 验证器)
将 Scout 作为 MCP 工具运行,供你的编码 Agent 在“扫描 → 修复 → 重新扫描”循环中调用——确定性、离线、零 Token、无需推理成本。Scout 负责发现问题;你的 Agent 负责修复;Scout 负责重新验证。
(GitHub 会移除 cursor:// 深层链接,因此 Cursor 徽章会跳转到网站上的一键按钮。)
安装为 Claude Code 插件
只需一条命令——插件已包含 MCP 服务,无需单独运行 claude mcp add:
/plugin marketplace add Varpost/Scout
/plugin install scout@scout
这会注册 scan_path 工具和 /scout-scan [path] 命令。要求 PATH 中已安装 uv——插件使用 uvx 启动服务(首次运行会下载软件包;之后的运行会使用缓存)。如果没有 uv?请使用下方的手动设置,运行 pip install "scout-security[mcp]",并改用 "command": "scout-mcp"。
手动设置(适用于任何 MCP 宿主)
所有 MCP 宿主使用相同的服务定义——通过 uv 零安装运行:
{
"mcpServers": {
"scout": {
"command": "uvx",
"args": ["--from", "scout-security[mcp]", "scout-mcp"]
}
}
}
没有 uv?运行 pip install "scout-security[mcp]",然后使用 "command": "scout-mcp",无需 args。
将此定义添加到以下位置:
| 宿主 | 位置 |
|---|---|
| Claude Code | 上方的插件,或 claude mcp add scout -- uvx --from "scout-security[mcp]" scout-mcp |
| Cursor | 项目中的 .cursor/mcp.json,或供所有项目使用的 ~/.cursor/mcp.json |
| Claude Desktop | claude_desktop_config.json(Settings → Developer → Edit Config) |
| Cline | cline_mcp_settings.json(MCP Servers → Configure MCP Servers) |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
| VS Code(原生 MCP) | .vscode/mcp.json——使用相同的服务对象,但应放在 "servers" 键下,而非 "mcpServers" |
它提供一个工具——scan_path(path)——返回与 --format json 相同的 Layer-3 JSON(包含发现项的文件、行号、严重性、稳定 ID、说明和修复指导)。让 Agent 在修复循环中调用该工具,并在修复后再次调用,以确认问题已解决。
将 Scout 与 AI 助手搭配使用
一句话概括其原理:Scout 确定性地发现问题 → 你的 AI 负责修复 → Scout 重新验证。 每次扫描都得到相同的发现,且始终零 Token——因此,重新检查修复结果不会产生推理成本。选择最符合你工作方式的使用方式;三种方式运行的都是同一引擎。
1. 你 + 聊天助手(Claude、Cursor、Copilot Chat)
scout scan . --format ai-prompt # writes security-prompts.md
打开 security-prompts.md,然后将一个代码块粘贴到你的助手中。每个代码块都是独立完整的,包含问题、修复方案,以及一条指示,要求扫描其余代码,查找同类问题。助手完成修改后,请重新验证:
scout scan . # clean? the loop is closed
2. 会自行调用 Scout 的 Agent(Claude Code、Cursor Agent)
接入 MCP 服务,然后让 Agent 执行以下循环:
使用 Scout 扫描此项目,修复所有问题,然后再次扫描——重复此过程,直到报告结果为零。
Agent 会调用 scan_path、应用修复,然后再次调用。Scout 是循环中的确定性零 Token 验证器,因此每次重新检查都是免费的。
3. CI / 提交前(强制执行循环)
将循环设为门禁——修复所有问题后,构建才会通过:
scout scan . --fail-on high # exit 1 on HIGH+ findings
有关 GitHub Action,请参阅用作 CI 门禁;有关在提交前发现问题,请参阅提交前钩子。要在现有仓库中采用 Scout?基线可以接受当前的问题,仅在出现新问题时才失败。
添加自定义扫描器
from scout.scanners import register_scanner
from scout.scanners.base import BaseScanner
from scout.models import Finding
from pathlib import Path
@register_scanner
class MyScanner(BaseScanner):
name = "my-scanner"
description = "Detects my custom pattern"
def scan_file(self, file_path: Path, content: str) -> list[Finding]:
findings = []
# detection logic here
return findings
在 scout/scanners/__init__.py 中添加一条导入语句,即可完成。
开发
git clone https://github.com/Varpost/Scout.git
cd Scout
pip install -e ".[dev,ai]"
pytest
ruff check scout/ tests/
文档
完整文档和交互式指南:https://varpost.github.io/Scout/
许可证
MIT——永久免费。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。