MrGoldzi/Sentinel-CLI

GitHub: MrGoldzi/Sentinel-CLI

Sentinel-CLI是一款本地化、确定性安全扫描工具,用于Git仓库和Web应用程序。

Stars: 1 | Forks: 0

Sentinel Logo ## **基于本地的确定性安全扫描器,用于 Git 仓库和 Web 应用程序。** [![Python 版本](https://img.shields.io/badge/python-3.8%2B-blue?logo=python&logoColor=white)](https://www.python.org/) [![许可证](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE) [![代码风格](https://img.shields.io/badge/code%20style-black-000000)](CONTRIBUTING.md#code-style) [![SARIF](https://img.shields.io/badge/SARIF-v2.1.0-orange)](https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html) **扫描 Git 仓库和 Web 应用程序以查找机密信息、易受攻击的依赖项、不安全的代码、OWASP Top 10 漏洞以及更多内容——优先离线,完全确定性,最小依赖。**
## 功能 - **机密信息扫描器** — 使用基于熵的回退机制,通过正则表达式模式匹配检测 40 多种 API 密钥、令牌、JWT、AWS 凭据、私钥、数据库连接字符串等 - **依赖项扫描器** — 自动检测 8 个包生态系统(PyPI、npm、Maven、Go、crates.io、RubyGems、Packagist、NuGet),默认情况下通过查询 **OSV.dev API**(谷歌的开源漏洞数据库)来提供全面、始终更新的 CVE 覆盖范围。相当于 Semgrep Supply Chain 的生态系统广度——无专有锁定。 - **静态分析** — 检测 70 多种不安全代码模式:`eval()`、`exec()`、`os.system()`、不安全的 `subprocess`、`pickle` 反序列化、SQL 注入、XSS、SSRF 等,跨越 6 种语言(Python、JS/TS、Go、Java、Ruby、PHP)使用正则表达式和 AST 分析 - **决策引擎** — 可配置的严重程度阈值(低/中/高/危急)以及清晰的退出代码,以便与 CI/CD 集成 - **三种输出格式** — 可读的终端输出、机器可读的 JSON 和 **SARIF v2.1.0**,用于 GitHub 高级安全 - **最小依赖** — 仅 3 个轻量级包(`pathspec`、`packaging`、`tqdm`);无 npm、无 Docker - **默认 OSV API** — 查询由谷歌维护的 OSV.dev 数据库(GHSA、PyPA、RustSec、Go vulndb、npm 建议书、OSS-Fuzz 等)以获取实时漏洞数据。使用 `--offline` 适用于断网环境。 - **测试仓库** — 包含一个具有故意漏洞的示例仓库以进行测试 - **DAST 测试服务器** — 包含一个位于 `test_servers/vulnerable_server.py` 的故意易受攻击的 HTTP 服务器,用于 DAST 测试 ## 为什么选择 Sentinel? | 功能 | Sentinel | Semgrep | 其他工具 | |---------|----------|---------|-------------| | 依赖项 | **3 个轻量级包** | 需要 npm/Docker | 常常需要 npm、Docker 或云服务 | | 漏洞数据库 | **OSV.dev API(默认)** — GHSA、PyPA、RustSec、Go vulndb、npm 建议书 | 专有 + GHSA | 常常是专有或 NVD-only | | 生态系统支持 | **8 个生态系统**(PyPI、npm、Maven、Go、crates.io、RubyGems、Packagist、NuGet) | 10 多个生态系统 | 变化很大 | | 网络 | **默认在线,通过 `--offline` 断网** | 需要网络 | 变化 | | 确定性 | **是 — 正则表达式 + 静态分析** | 是 — 基于 AST 的规则 | 常常使用 ML/启发式方法,结果可变 | | CI/CD 准备 | **退出代码 + SARIF + JSON** | SARIF + JSON | 变化很大 | | 复杂性 | **一个 CLI 命令** | 复杂的 YAML 规则 | 常常需要复杂的配置 | | 准确性 | **被动、确定性分析** | AST + 数据流可达性 | 常常使用主动利用或启发式模型 | | 开放数据 | **100% 开源 OSV 数据库** | 混合开源/专有 | 常常是专有 | | 断网 | **是(`--offline` 模式)** | 需要网络 | 很少支持 | Sentinel 适用于: - **CI/CD 管道**,您希望在无需拉取 npm/Docker 的情况下进行全面的、始终更新的安全检查 - **多语言单体仓库** — 自动检测 8 个生态系统的依赖文件 - **断网环境** — 使用 `--offline` 标志和内置漏洞数据库 - **学习和教育** — 代码库小、结构良好、易于理解 - **在提交代码之前进行快速本地扫描** - **替换 Semgrep Supply Chain** — 相似的生态系统覆盖范围,零专有锁定 ## 快速入门 ``` # 安装自 PyPI pip install sentinel-security # 扫描包含的测试仓库 sentinel scan test_repo # 扫描任何本地目录 sentinel scan /path/to/your/project # 对 Web 应用进行 DAST 扫描 sentinel dast https://example.com # 输出为 GitHub Code Scanning 的 SARIF 格式 sentinel scan . --output sarif -o results.sarif ``` ## 安装 Sentinel 需要 **Python 3.8+**。通过 pip 安装或直接从源运行。 ### 从 PyPI(推荐) ``` pip install sentinel-security sentinel scan /path/to/repo sentinel dast https://example.com ``` ### 从源 ``` git clone https://github.com/your-org/sentinel.git cd sentinel pip install -r requirements.txt ``` ### 如何运行 Sentinel 安装后,直接使用 `sentinel` 命令: ``` sentinel scan /path/to/repo sentinel dast https://example.com ``` 如果您在没有安装的情况下从克隆的仓库工作,请使用以下之一: ``` # 作为 Python 模块运行 python -m sentinel scan /path/to/repo # 或使用包装脚本 python cli.py scan /path/to/repo ``` 要将 `sentinel` 作为系统命令从源安装,以可编辑模式安装: ``` pip install -e . sentinel scan /path/to/repo # now works from anywhere ``` ### 依赖项 Sentinel 依赖于 **3 个轻量级运行时包**: | 包 | 目的 | |---------|---------| | `pathspec` | .gitignore 规则匹配用于文件发现 | | `packaging` | 语义版本比较用于依赖项漏洞 | | `tqdm` | 扫描期间的进度条 | 不需要重框架(Docker、npm、Node.js)。 ### `sentinel` 与 `python -m sentinel` 如果您通过 `pip install sentinel-security` 或 `pip install -e .` 安装,请使用: ``` sentinel scan /path/to/repo ``` 如果您在没有安装的情况下从克隆的仓库运行,请使用: ``` python -m sentinel scan /path/to/repo # 或 python cli.py scan /path/to/repo ``` 所有 CLI 标志和命令都以相同的方式工作。 ## CLI 参考文档 ### `scan` 命令 ``` sentinel scan [options] ``` **参数:** | 参数 | 描述 | |----------|-------------| | `path` | 要扫描的仓库的路径(必需) | **选项:** | 选项 | 描述 | |--------|-------------| | `--output {human,json,sarif}` | 输出格式。`human`(默认)用于终端,`json`用于机器解析,`sarif`用于 GitHub 高级安全。 | | `--output-file FILE`, `-o FILE` | 将输出写入文件。结合使用 `--output` 或单独使用。 | | `--json [FILE]` | *(旧版)* 以 JSON 格式输出。使用 `--output json` 代替。 | | `--sarif [FILE]` | *(旧版)* 以 SARIF 格式输出。使用 `--output sarif` 代替。 | | `--all`, `--scan-all` | 扫描 **所有** 文件——无二进制/源过滤,无 `.gitignore` 尊重,无目录跳过。最大覆盖模式。 | | `--offline` | 使用本地漏洞数据库而不是 OSV API。适用于断网环境或更快的 CI 扫描。 | | `--no-gitignore` | 在扫描中包含 `.gitignored` 文件(例如,`.env` 文件、凭据转储)。 | | `--stats` | 显示详细的扫描统计信息:文件类型细分、每个扫描器的计时、条形图。 | | `--exclude PATTERNS` | 以逗号分隔的 gitignore 样式模式,用于排除(例如,`--exclude "*.test.py,docs/*"`)。 | | `--include PATTERNS` | 以逗号分隔的 gitignore 样式模式,仅扫描(例如,`--include "*.py,*.js,*.yaml"`)。 | | `--verbose`, `-v` | 在扫描期间显示详细输出 | | `--severity-threshold {LOW,MEDIUM,HIGH,CRITICAL}` | 触发 BLOCK 的最低严重程度。默认:高。`CRITICAL` 阈值仅在发现危急问题时才会阻止。 | | `--help` | 显示帮助信息 | ### `--version` ``` sentinel --version # > Sentinel v0.3.0 ``` ## 退出代码 | 代码 | 结论 | 默认阈值(高) | 中等阈值 | 低阈值 | 危急阈值 | |------|---------|--------------------------|------------------|---------------|-------------------| | `0` | ✅ 通过 | 无问题或仅低 | 无问题 | 无问题 | 无问题 | | `1` | ⚠️ 警告 | 发现中等问题 | 发现低问题 | — | 发现中等或高问题 | | `2` | ❌ 阻止 | 发现高问题 | 发现中等+问题 | 任何问题 | 发现危急问题 | ``` # 退出代码在 CI/CD 管道中自然工作 sentinel scan . --severity-threshold MEDIUM if [ $? -eq 2 ]; then echo "Security issues found — blocking build" exit 1 fi ``` ## 输出格式 ### 可读的(默认) ``` sentinel scan test_repo ``` 显示一个带颜色的摘要,按文件、严重程度徽章和行引用分组查找结果。 ### JSON ``` sentinel scan test_repo --output json -o report.json ``` 机器可读的 JSON,包含结论、总查找结果、文件列表和所有查找详细信息。
示例 JSON 输出 ``` { "verdict": "BLOCK", "total_findings": 30, "scanned_files": 4, "scan_time_ms": 12.34, "severity_threshold": "HIGH", "findings": [ { "file_path": "app.py", "line_number": 9, "issue_type": "static_analysis", "severity": "HIGH", "message": "Use of eval() detected. eval() can execute arbitrary code and is a security risk.", "rule_id": "SAF-EVAL", "confidence": 1.0, "snippet": "result = eval(user_input)" } ] } ```
### SARIF v2.1.0 ``` sentinel scan test_repo --output sarif -o report.sarif ``` 与 [GitHub 高级安全](https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/sarif-support-for-code-scanning)、Azure DevOps 和其他 SARIF 兼容工具兼容的行业标准格式。 ``` # 上传到 GitHub Code Scanning(需要 GitHub CLI) gh api /repos/:owner/:repo/code-scanning/sarifs \ -f commit_sha="$(git rev-parse HEAD)" \ -f sarif="$(cat report.sarif | base64 -w0)" ``` SARIF 输出已根据 **官方 OASIS SARIF v2.1.0 JSON 架构**(Errata 01)进行验证——100% 兼容。
示例 SARIF 输出 ``` { "$schema": "https://json.schemastore.org/sarif-2.1.0.json", "version": "2.1.0", "runs": [ { "tool": { "driver": { "name": "Sentinel", "version": "0.3.0", "informationUri": "https://github.com/sentinel-security/sentinel", "rules": [ { "id": "SEC-aws-access-key", "name": "Aws Access Key", "shortDescription": { "text": "AWS Access Key ID detected" }, "defaultConfiguration": { "level": "error" }, "properties": { "severity": "HIGH", "issueType": "secret", "tags": ["security", "secret"] } } ] } }, "results": [ { "ruleId": "SEC-aws-access-key", "level": "error", "message": { "text": "AWS Access Key ID detected in configuration file." }, "locations": [{ "physicalLocation": { "artifactLocation": { "uri": "config.py", "uriBaseId": "%SRCROOT%" }, "region": { "startLine": 5 } } }] } ], "invocations": [ { "executionSuccessful": true } ], "properties": { "verdict": "BLOCK", "total_findings": 30, "scanned_files": 4, "scan_time_ms": 12.34, "severity_threshold": "HIGH" } } ] } ```
``` # 自行验证 SARIF 输出 sentinel scan test_repo --output sarif -o report.sarif python scripts/validate_sarif.py report.sarif # > ✅ SARIF 输出符合官方模式。 ``` ## 示例 ### 基本扫描 ``` $ sentinel scan test_repo 🔍 Sentinel v0.3.0 - Scanning: /path/to/test_repo Threshold: HIGH This may take a moment... ═══════════════════════════════════════ Sentinel Security Scan Report ═══════════════════════════════════════ Summary: Files scanned: 4 Findings found: 30 Severity threshold: [HIGH] Scan time: 12ms File types: .py: 2, .txt: 1, .yml: 1 Findings by severity: 14 HIGH 9 MEDIUM 7 LOW Findings by type: 🔑 Secrets: 10 ⚠️ Static Analysis: 18 📦 Dependencies: 2 Detailed findings: 📄 app.py [HIGH] ⚠️ Use of eval() detected... line 9 SAF-EVAL └─→ result = eval(user_input) method: regex confidence: 100% fix: Replace eval() with safer alternatives like ast.literal_eval() or a proper parser. 📄 config.py [HIGH] 🔑 AWS Access Key ID detected... line 12 SEC-aws-access-key └─→ AWS_ACCESS_KEY_ID = "AKIA..." method: regex confidence: 90% fix: Rotate the key immediately. Use IAM roles or temporary credentials via STS instead of long-lived keys. ──────────────────────────────────────── Verdict: BLOCK Exit code: 2 ──────────────────────────────────────── ``` ### 扫描所有文件(全面覆盖) 默认情况下,Sentinel 跳过二进制文件、常见的依赖项目录(`node_modules`、`.venv`)和 `.gitignored` 文件。使用 `--all` 扫描 **所有** 文件: ``` # 扫描所有内容 — 二进制文件、node_modules、.git,等等 sentinel scan /path/to/repo --all # 包含 .gitignored 文件,但仍跳过二进制文件/依赖项 sentinel scan /path/to/repo --no-gitignore # 仅扫描特定文件类型 sentinel scan /path/to/repo --include "*.py,*.yaml,*.env" # 排除测试文件进行扫描 sentinel scan /path/to/repo --exclude "tests/*,docs/*" ``` ### 查看详细的扫描统计信息 ``` # 显示文件类型细分、每个扫描器的计时和直方图 sentinel scan /path/to/repo --stats ``` 输出包括: - 文件扩展名分布条形图 - 每个扫描器的计时细分(文件发现、依赖项扫描、并行扫描) - 按问题类型拆分的查找结果(机密信息、静态分析、依赖项) ### OSV API(默认)提供全面、始终更新的漏洞数据 Sentinel 默认查询 **OSV.dev API** — 谷歌、GitHub 和 OpenSSF 使用的相同开源漏洞数据库。涵盖来自以下来源的漏洞: - **GitHub 安全建议书(GHSA)** — 行业标准的严重程度评级 - **PyPA 建议数据库** — 官方 Python 打包漏洞 - **RustSec 建议数据库** — Rust crate 漏洞 - **Go 漏洞数据库** — 官方 Go 模块漏洞 - **npm 安全建议书** — Node.js 包漏洞 - **OSS-Fuzz 发现** — 持续模糊测试的开源项目结果 #### 多生态系统自动检测 Sentinel 自动检测并扫描所有主要生态系统中的依赖项文件: | 生态系统 | 检测到的文件 | |-----------|---------------| | **PyPI**(Python) | `requirements.txt`、`Pipfile`、`Pipfile.lock` | | **npm**(JavaScript/TypeScript) | `package.json`、`package-lock.json`、`yarn.lock`、`pnpm-lock.yaml` | | **Maven**(Java/Kotlin) | `pom.xml`、`build.gradle`、`build.gradle.kts` | | **Go** | `go.mod`、`go.sum` | | **crates.io**(Rust) | `Cargo.toml`、`Cargo.lock` | | **RubyGems**(Ruby) | `Gemfile`、`Gemfile.lock` | | **Packagist**(PHP) | `composer.json`、`composer.lock` | | **NuGet**(.NET) | `packages.config`、`*.csproj` | 无需配置——只需将 Sentinel 指向您的仓库,它就会找到所有内容。 ### 更改严重程度阈值 ``` # 更严格:任何发现(即使是 LOW)都会导致 BLOCK sentinel scan test_repo --severity-threshold LOW # 默认:只有 HIGH 发现会导致 BLOCK sentinel scan test_repo ``` ### CI/CD 集成 #### GitHub Actions 在 `.github/workflows/sentinel-scan.yml` 中包含一个现成的工作流程: ``` name: Sentinel Security Scan on: push: branches: [main, master] pull_request: branches: [main, master] schedule: - cron: "0 6 * * 1" workflow_dispatch: permissions: contents: read security-events: write jobs: sentinel-scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.11" cache: "pip" - name: Install Sentinel run: pip install sentinel-security - name: Run Sentinel id: sentinel continue-on-error: true run: | sentinel scan . --sarif sentinel-results.sarif --severity-threshold MEDIUM || exit_code=$? echo "exit_code=${exit_code:-0}" >> "$GITHUB_OUTPUT" - name: Upload SARIF to GitHub Code Scanning uses: github/codeql-action/upload-sarif@v3 with: sarif_file: sentinel-results.sarif category: sentinel - name: Display scan summary if: always() run: | EXIT_CODE="${{ steps.sentinel.outputs.exit_code }}" echo "### Sentinel Security Scan Results" >> "$GITHUB_STEP_SUMMARY" if [ "$EXIT_CODE" = "2" ]; then echo "🔴 **BLOCKED** - High severity security issues detected!" >> "$GITHUB_STEP_SUMMARY" elif [ "$EXIT_CODE" = "1" ]; then echo "🟡 **WARNING** - Medium severity issues found" >> "$GITHUB_STEP_SUMMARY" else echo "🟢 **PASS** - No security issues found" >> "$GITHUB_STEP_SUMMARY" fi ``` 查找结果将出现在您的仓库的 **安全 > 代码扫描** 下。 #### 通用 CI ``` sentinel scan . --output json -o report.json --severity-threshold MEDIUM exit_code=$? case $exit_code in 0) echo "✅ PASS: No security issues" ;; 1) echo "⚠️ WARNING: Low severity issues found" ;; 2) echo "❌ BLOCKED: Security issues found! See report.json" ;; esac exit $exit_code ``` ## 扫描器 ### DAST 扫描器(动态应用程序安全测试) DAST 扫描器使用安全的 HTTP 请求对 Web 应用程序和 API 进行被动、观察性的安全分析。无利用、无破坏性有效负载、无暴力破解。覆盖 OWASP Top 10 的 29 个检测阶段: | 阶段 | 检查 | 规则 ID 前缀 | 严重程度 | |-------|-------|---------------|----------| | 1 | 初始侦察和连接 | `DAST-CONNECTION-ERROR` | 低 | | 2 | 安全头(HSTS、CSP、X-Frame-Options 等) | `DAST-STRICT-TRANSPORT-SECURITY` 等。 | 低–高 | | 3 | Cookie 安全(Secure、HttpOnly、SameSite 标志) | `DAST-COOKIE-NO-SECURE` 等。 | 中–高 | |4 | CORS 配置错误(通配符来源、凭据) | `DAST-CORS-WILDCARD` 等。 | 中–高 | | 5 | TLS/HTTPS 评估(版本、加密) | `DAST-NO-HTTPS`、`DAST-WEAK-TLS` | 高 | | 6 | 服务器信息泄露(服务器头、X-Powered-By、调试模式) | `DAST-SERVER-INFO-DISCLOSURE` 等。 | 低–高 | | 7 | 注入反射(SQL、NoSQL、命令、LDAP、XPath) | `DAST-INJECTION-SQL` 等。 | 高–危急 | | 8 | XSS 反射检测 | `DAST-XSS-REFLECTED` | 高 | | 9 | 服务器端模板注入(SSTI) | `DAST-SSTI` | 中–危急 | | 10 | 意图端点发现(管理员、调试、.env、.git) | `DAST-EXPOSED-*` | 低–危急 | | 11 | 详细错误消息检测(堆栈跟踪、SQL 错误) | `DAST-VERBOSE-ERROR-*` | 中–高 | | 12 | 目录列出启用 | `DAST-DIRECTORY-LISTING` | 中 | | 13 | 身份验证检查(通过 HTTP 登录、用户枚举) | `DAST-LOGIN-OVER-HTTP`、`DAST-USER-ENUMERATION` | 中–危急 | | 14 | 访问控制 / IDOR(不安全的直接对象引用) | `DAST-IDOR-POTENTIAL` | 高 | | 15 | 重定向检测 | `DAST-OPEN-REDIRECT` | 中 | | 16 | ReDoS 模式检测 | `DAST-REDOS`、`DAST-REDOS-TIMING` | 中–高 | | 17 | XXE & 不安全反序列化指标 | `DAST-XXE-POTENTIAL`、`DAST-INSECURE-DESERIALIZATION` | 中–高 | | 18 | JWT 配置错误(alg: none、无过期、对称算法) | `DAST-JWT-ALG-NONE` 等。 | 低–危急 | | 19 | 速率限制评估 | `DAST-NO-RATE-LIMITING` | 低 | | 20
标签:Apache 2.0, CMS安全, Git 安全, Go, JavaScript, OpenVAS, OWASP Top 10, PHP, Python, Ruby, Ruby工具, SARIF, Web 应用安全, XML 请求, 代码安全, 安全合规, 安全开发, 安全漏洞, 开源许可证, 指令劫持, 无后门, 漏洞枚举, 知识库, 秘密检测, 网络代理, 逆向工具, 错误基检测, 静态代码分析