Yusuf-Gadelrab/dira
GitHub: Yusuf-Gadelrab/dira
面向初创公司的零依赖 Python 代码库安全扫描器,一条命令完成密钥泄露、依赖漏洞、配置错误、许可证风险检测并输出安全就绪评分与 SBOM。
Stars: 0 | Forks: 0
# DIRA · درع
**面向初创公司代码库的安全审计。** 一条命令,零依赖。
`secrets` · `dependency CVEs` · `misconfigurations` · `licenses` · `git-history leaks` · `live surface` · `SBOM` · `readiness score`
[](https://github.com/Yusuf-Gadelrab/dira/actions/workflows/tests.yml)
[](tests/)
[](LICENSE)
[](pyproject.toml)
[](pyproject.toml)
DIRA 是一个面向初创公司代码库的零依赖 Python 安全扫描器,只需一条命令即可发现硬编码的 secrets、依赖项 CVE、配置错误、许可证风险以及 git 历史记录泄露,随后打印出安全就绪评分、SBOM 以及针对其发现的所有问题的确切修复方案。
大多数初创公司的安全工具要么是每月 2000 美元的平台,要么是你从未配置过的五个独立 CLI。DIRA 用一条命令且无需安装占用,直接回答了创始人实际会被问到的问题——*“这个代码库是否足够安全以卖给企业?”*
```
pipx install git+https://github.com/Yusuf-Gadelrab/dira@v1.2.0
dira scan . # scan the current project
dira scan . -t yourapp.com # + audit the live domain
dira scan . -f html -o report.html --open
```
## 它会检查什么
| 扫描器 | 发现内容 |
|---|---|
| `secrets` | 24 种凭证模式(AWS、Stripe、OpenAI、Anthropic、GitHub、GCP、Slack、npm、DSN、私钥)以及一条基于熵限制的通用规则。值在每份报告中都会被**打码**。 |
| `config` | 涵盖 Docker(root 用户、`:latest`、build-ARG secrets)、compose/k8s(`privileged`、hostPath)、Terraform(`0.0.0.0/0`、公开存储桶、未加密存储)、GitHub Actions(`pull_request_target`、可变 action 引用、脚本注入)、云(公开的 Firebase 规则、`"Principal": "*"`、GCP `allUsers`、`curl \| sh`)、前端(`NEXT_PUBLIC_*` secrets、localStorage 中的 token、innerHTML/`dangerouslySetInnerHTML`、通配符 `postMessage`、JWT `none`)、LLM 应用(`dangerouslyAllowBrowser`、prompt 拼接、模型输出通过管道传递给执行器)以及服务端代码(通过字符串拼接导致的 SQLi、`shell=True`、通配符 CORS、禁用 TLS 验证、`eval`/`pickle`、弱密码哈希、开启 debug 模式)的 38 条规则。 |
| `deps` | 根据 **OSV.dev** 解析 lockfile 中的每一个包——支持 npm、PyPI、Go、crates.io、RubyGems。批量处理、免费、无需 API key,并提供 CVSS 预估的严重程度和确切修复版本。 |
| `git` | 深埋在提交历史中的 secrets(删除文件并不能轮换密钥)、被追踪的 `.env`/`.pem`/keystores、远程 URL 中的凭证、`.gitignore` 缺漏。 |
| `surface` | 线上域名:TLS 有效期与过期时间、HSTS/CSP/nosniff/frame-options、cookie 标志、HTTP→HTTPS 重定向、版本泄露 headers,以及公开暴露的 `/.env`、`/.git/config`、`/actuator/env`。 |
| `licenses` | 从 npm/PyPI 解析的每个依赖项的许可证,被归类为宽松型、文件级 copyleft(MPL/LGPL)、强 copyleft(GPL)和网络 copyleft(AGPL/SSPL)——并提供用于尽职调查文档的许可证清单。 |
| `readiness` | 一个基于 SOC 2 审计员和企业安全问卷实际要求的 18 项检查、80 分的**初创公司安全就绪评分**(以百分比报告)——涵盖 lockfile、Dependabot、CI、测试、secret 扫描、SAST、CODEOWNERS、SECURITY.md、IaC、可观测性、事件响应、备份、隐私。 |
每一项发现都包含严重程度、位置、打码的证据、具体的修复建议以及 CWE/OSV 引用。
## 对比情况
DIRA 在一条命令中完成五件事。每一件事都有专门针对该特定事项做得更好的工具。请同时使用它们——DIRA 并不打算取代其中任何一个,并且是刻意这样声明的:
| | DIRA | gitleaks | trufflehog | semgrep |
|---|---|---|---|---|
| Secret 检测 | 模式 + 熵,打码处理 | 基于模式,规则集更成熟 | 基于模式 **+ 针对提供商的在线验证** | 非其重点 |
| 依赖项 CVE (OSV.dev) | 支持,5 个生态系统 | 不支持 | 不支持 | 不支持(Semgrep Supply Chain 是独立的付费产品) |
| 配置/IaC 配置错误 | 支持,38 条规则 | 不支持 | 不支持 | 支持——具有 DIRA 所缺乏的真正的数据流分析 |
| Git 历史泄露扫描 | 支持 | 支持——这是它的全部工作,更成熟 | 支持 | 不支持 |
| 许可证风险 / SBOM | 支持(CycloneDX + SPDX) | 不支持 | 不支持 | 不支持 |
| 数据流 / 污点分析 | **不支持**——仅支持模式匹配 | 不支持 | 不支持 | **支持**——这是 semgrep 的核心优势 |
| 已验证(不仅限于匹配的)secrets | **不支持** | 不支持 | **支持** | 不支持 |
| 初创公司就绪评分 | 支持,18 项检查 / 80 分 | 不支持 | 不支持 | 不支持 |
| 安装 | pipx/uvx,**零依赖** | 单个 Go 二进制文件 | 单个 Go 二进制文件 | pip/brew,带有依赖 |
**客观评价:** 如果 secrets 是你唯一关心的问题,gitleaks 和 trufflehog 在这方面更加成熟,而且 trufflehog 会针对在线提供商验证密钥——DIRA 不会。如果你需要真正的数据流分析,semgrep 是一个不同且更深入的工具;DIRA 寻找的是*sinks*(`innerHTML =`、通过拼接构建的 SQL、`shell=True`),而不是经过证明、追踪的漏洞。DIRA 拥有而上述三者都没有的是:依赖项许可证风险、SBOM,以及一个基于企业安全问卷实际要求的就绪评分——因为大多数时候,问题不是“这个文件里有什么故障”,而是“我们能通过采购审核吗”。
## 示例输出
这是一个针对小型演示项目的实际运行结果,该项目包含硬编码的 Stripe key、字符串拼接的 SQL、禁用 TLS 验证、root Docker 用户以及过时的 `lodash`:
```
╔══════════════════════════════════════════════════════════════════════════╗
║ DIRA ║
║ درع · security audit for startups ║
╚══════════════════════════════════════════════════════════════════════════╝
Target /tmp/demo
SECURITY GRADE F risk 100/100
STARTUP READINESS 18% Pre-security (14/80 pts)
CRITICAL 2 HIGH 5 MEDIUM 8 LOW 9 INFO 5
─── CRITICAL ──────────────────────────────────────────────────────────
● lodash 4.17.11 — CVE-2019-10744: Prototype Pollution in lodash
package-lock.json npm:lodash@4.17.11
→ Upgrade lodash to 4.17.12 or later.
● Stripe secret/restricted key
src/app.py:2 sk_l************nZaQ
→ Revoke the key at the provider, issue a new one, move it to a secret manager, and purge it from git history (git filter-repo / BFG).
─── HIGH ──────────────────────────────────────────────────────────────
● SQL built by string concatenation
src/app.py:4 execute("SELECT * FROM users WHERE id = " +
→ Use parameterized queries / bound placeholders.
● TLS verification disabled
src/app.py:5 verify=False
→ Never disable certificate verification; pin a CA bundle instead.
─── MEDIUM ────────────────────────────────────────────────────────────
● GitHub Action pinned to a mutable ref
.github/workflows/ci.yml:6 - uses: actions/checkout@v4
→ Pin third-party actions to a full commit SHA — tags are mutable and are a live supply-chain risk.
● Container runs as root
Dockerfile:1 no non-root USER directive
→ Create an unprivileged user and add `USER app` before CMD/ENTRYPOINT.
16 files · 1 deps · 1.8s
```
注意这里的打码处理——`sk_l************nZaQ`。DIRA 绝不会将完整的凭证写入报告,因此 HTML 和 SARIF 输出可以安全地与客户分享或附加到工单中。
## 安装
```
# 从源码(现已提供)
pipx install git+https://github.com/Yusuf-Gadelrab/dira@v1.2.0
uvx --from git+https://github.com/Yusuf-Gadelrab/dira@v1.2.0 dira scan .
pip install git+https://github.com/Yusuf-Gadelrab/dira@v1.2.0
# 或从 release 获取 wheel
pipx install https://github.com/Yusuf-Gadelrab/dira/releases/download/v1.2.0/dira_scan-1.2.0-py3-none-any.whl
```
## 使用方法
```
dira scan . # human report
dira scan . --verbose # every occurrence + the readiness checklist
dira scan . --only secrets,config # fast pre-commit-grade pass
dira scan . --diff origin/main # only files changed on this branch (PR gate)
dira scan . --offline # air-gapped: no OSV, no live checks
dira scan . -f sarif -o dira.sarif # GitHub code scanning
dira scan . -f markdown # paste into a PR
dira scan . -f html -o report.html --open # client-shareable audit
dira baseline . # accept today's debt, fail only on new issues
dira rules # every rule, printed
dira init # install CI workflow + pre-commit hook
dira sbom . -f cyclonedx -o sbom.json # CycloneDX 1.5 (or -f spdx for SPDX 2.3)
dira fix . # preview the safe remediations
dira fix . --apply --contact you@yourdomain.com
```
当发现任何等于或高于 `--fail-on`(默认为 `high`)的严重程度时,退出码为 `1`,因此可以直接将其接入 CI。`--fail-on never` 将始终以 `0` 退出。
### GitHub Actions
```
- uses: Yusuf-Gadelrab/dira@v1.2.0 # or @v1 — a moving major tag
with:
fail-on: high
target: yourapp.com
```
或者使用 SARIF 路径,让检查结果显示在 Security 标签页中——`dira init` 会为你编写该工作流。
### pre-commit
```
repos:
- repo: https://github.com/Yusuf-Gadelrab/dira
rev: v1.2.0
hooks:
- id: dira
```
### `dira fix` —— 搞定无聊的 80%
仅包含附加、可逆的更改:
- 追加你的 `.gitignore` 缺失的 secret 模式;
- 编写包含真实披露 SLA 的 `SECURITY.md`;
- 为其检测到的每个生态系统编写 `.github/dependabot.yml`;
- 从你的 `.env` 推导出 `.env.example`——**仅包含名称,绝不复制值**;
- 编写 `docs/INCIDENT-RESPONSE.md`(严重程度、最初 30 分钟、72 小时通知);
- 为静态站点发布 `/.well-known/security.txt`。
它绝不触碰应用代码,绝不重写 git 历史记录,也绝不轮换密钥——这些会作为清单打印出来,因为一个静默“修复”泄露凭证的工具是在骗你。默认进行试运行;使用 `--apply` 写入。
### `dira sbom` —— 因为企业买家会问这个
生成 CycloneDX 1.5 或 SPDX 2.3,源自 CVE 扫描已经执行过的相同 lockfile 解析,并带有正确的包 URL(`pkg:npm/%40scope/pkg@1.0.0`)。只需额外耗费一秒钟。
### 作为库使用
```
from dira import scan
result = scan(Path("."), offline=True)
print(result.grade(), result.risk_score(), result.readiness["score"])
for f in result.findings:
print(f.severity, f.path, f.title, f.remediation)
```
## 它为什么快
- **一次遍历,两套正则。** 24 种 secret 模式被编译成一个单一交替(alternation)组,因此每个文件只被读取一次,而不是按每条规则匹配一次。对 23 种特定提供商模式的第二轮扫描会同时进行,因为正则表达式交替优先匹配最左侧,否则在同一行内,会让宽泛的通用规则覆盖特定的规则(`API_KEY = "sk_live_…"` 必须被报告为 Stripe key,而不是作为通用凭证)。
- **增量缓存。** `.dira-cache.json` 根据 `(size, mtime, ruleset version)` 缓存结果;未更改的文件永远不会被重新读取。在一个包含 117 个文件的仓库中测试,文件扫描阶段的时间在第二次运行时从 1.56 秒降至 0.05 秒。请注意,这仅缓存*文件*扫描——git 历史记录扫描不会被缓存,并且在历史记录深厚的仓库中会在完整运行时占据主导地位,因此对于内部的快速迭代环节,请使用 `--only secrets,config`(或 `--history 0`)。
- **默认并行。** 文件扫描和 OSV 详情查询在与你 CPU 匹配的线程池中运行。
- **批量网络请求。** 每个 OSV 请求最多包含 900 个包,并发获取并设有上限的咨询详情。
- **低成本的跳过。** Vendor/build 目录、`.gitignore` 条目、二进制文件以及大于 2 MB 的文件会在任何 I/O 操作之前被排除。
- **Diff 模式。** `--diff origin/main` 仅扫描该分支触及的内容——这是一个在测试任务开始前就能完成的 PR 门禁。
## 噪声控制
误报是导致安全工具被卸载的原因,因此 DIRA 会:
- 忽略占位符、`os.environ[...]`、`${VAR}`、`changeme`、`xxxx` 和低熵值;
- 对 Shannon 熵 ≥ 3.4 的通用凭证规则设置门控;
- **降级**——而不是隐藏——`tests/`、`fixtures/`、文档和 `.env.example` 中的命中项;
- 对同一行上的重叠规则进行去重——当特定提供商的规则指明了某种凭证时,通用的兜底规则将被抑制,而不会被重复报告;
- 支持 `.diraignore`(语法与 `.gitignore` 相同)以及稳定的按问题生成的指纹,因此 `dira baseline` 可以抑制当前的遗留问题,而不会掩盖明天可能出现的新回归问题。
## 局限性 —— 请阅读这些内容
自动化的模式分析。它**不能**替代渗透测试、威胁建模或真正的 SOC 2 审计,并且它无法查看你的云 IAM、你的 MFA 状态或你的访问权限审查(这些在报告中会被列为手动证明)。一次干净的 DIRA 运行意味着“此仓库中没有已知的错误模式”,而不是“安全”。
扫描你不拥有或没有测试权限的域名可能是非法的。`--target` 会对少数几个众所周知的路径执行未经身份验证的 GET 请求——请仅将其指向你自己的基础设施。
## 许可证
MIT © Yusuf Gadelrab
## 关于作者
由 **Yusuf Gadelrab** 开发——圣何塞州立大学计算机科学系学生(计算机科学理学学士,预计 2028 年 5 月毕业)、AI/ML 构建者,同时也是 2026 年 SIGCSE 技术研讨会(关于计算机科学教育)两篇经同行评审的论文的合著者([DOI 10.1145/3770761.3777339](https://doi.org/10.1145/3770761.3777339))。
- 个人作品集:标签:SBOM生成, StruQ, 逆向工具