malandas/andas

GitHub: malandas/andas

一款专注于真实风险验证的跨平台安全 CLI 工具,通过实时验证凭证有效性和分析依赖漏洞可达性来过滤告警噪音。

Stars: 0 | Forks: 0

# andas [![ci](https://static.pigsec.cn/wp-content/uploads/repos/cas/99/993938d8ce5e902ccfb9d6747725c320d855dea3235ed9a304cedf0d94c9321f.svg)](https://github.com/malandas/andas/actions/workflows/ci.yml) [![release](https://img.shields.io/github/v/release/malandas/andas)](https://github.com/malandas/andas/releases/latest) [![license](https://img.shields.io/github/license/malandas/andas)](LICENSE) 大多数安全扫描器会让你淹没在警报中。`andas` 回答了它们无法回答的问题:**对于*你的*项目来说,这种风险是真实存在的,还是无用的噪音?** - 只有当检测到的密钥**仍然有效**时,它才构成紧急事件。`andas` 会以安全、只读的方式询问其提供商,并将失效的凭证降级,使其不再干扰你。 - 只有当 npm 依赖项中的 CVE **可从**你应用自身的代码到达时,它才至关重要。`andas` 会追踪你的 import 语句,并将无人 import 的包以及永远不会发布到生产环境的开发依赖项中的漏洞降级。 一个命令。一个无依赖的二进制文件。支持 Linux、macOS、Windows。 ## 安装 从[最新发布版本](https://github.com/malandas/andas/releases/latest)获取预编译的二进制文件: ``` # macOS (Apple Silicon) 示例 curl -sSL -o andas https://github.com/malandas/andas/releases/latest/download/andas-darwin-arm64 chmod +x andas && ./andas version ``` 使用 Go 工具链: ``` go install github.com/malandas/andas@latest # 或者从 clone 获取: go build -o andas . ``` ## 用法 ``` andas scan # scan the current directory andas scan ./myproject # scan a specific path andas scan . --history # also sweep git history for removed secrets andas scan . --html out.html # write a shareable HTML report andas scan . --sarif r.sarif # SARIF for CI / GitHub code scanning andas scan . --json # machine-readable output andas scan . --offline # no network calls at all ``` ### 在已有技术债务的仓库中采用 ``` andas scan . --baseline andas-baseline.json --update-baseline # accept today's state andas scan . --baseline andas-baseline.json # now only NEW risk fails CI ``` ### 保护你的提交 ``` andas hook install # installs a git pre-commit hook andas hook status # is it installed? andas hook uninstall # remove it ``` 该 hook 会在每次提交前运行 `andas scan . --offline --fail-on medium`,因此硬编码的密钥会在**进入历史记录之前**被捕获——这是你永远无法完全撤销的泄漏。使用 `git commit --no-verify` 可以跳过误报。 ### 忽略路径 在仓库根目录下放置一个 `.andasignore` 文件,每行一个模式(类似于 `.gitignore`):路径片段(`testdata`、`src/generated`)、glob 匹配(`*.min.js`)或 `#` 注释。匹配的文件将被工作区扫描器跳过。 ### 参数标志 | 标志 | 默认值 | 含义 | |------|---------|---------| | `--history` | off | 同时扫描完整的 git 历史,查找从 HEAD 中移除的密钥。 | | `--baseline ` | — | 抑制记录在此基线文件中的发现结果。 | | `--update-baseline` | off | 接受所有当前的发现结果到 `--baseline` 中,然后退出。 | | `--no-entropy` | off | 禁用基于信息熵的未知/自定义密钥检测。 | | `--html ` | — | 生成一个独立的 HTML 报告。 | | `--sarif ` | — | 生成用于 CI / 代码扫描的 SARIF 2.1.0 报告。 | | `--markdown ` | — | 生成 PR 评论风格的 Markdown 报告。 | | `--no-validate` | off | 跳过密钥的有效性验证。 | | `--offline` | off | 完全不进行网络调用(不验证,不进行 OSV 查询)。 | | `--json` | off | 输出 JSON 而非表格。 | | `--no-color` | off | 禁用彩色输出。 | | `--timeout` | `8` | 每次验证的网络超时时间(秒)。 | | `--fail-on` | `high` | 当真实风险达到此级别时以非零状态退出。 | 当**真实**风险达到 `--fail-on` 设定的级别时,退出代码为非零,因此你可以基于有效的密钥来控制 CI pipeline 的流转,同时忽略已失效的密钥。 ## 真实风险评分的工作原理 每个发现结果都包含两个级别: - **严重性** — 理论/基于模式的级别(其他工具提供给你的结果)。 - **真实风险** — 经过 `andas` 的上下文检查后: - 密钥**验证为有效** → 提升至 `CRITICAL` - 密钥**验证为失效** → 降级至 `INFO`(这就是我们要剔除的噪音) - 无法验证 → 保持其理论上的严重性 ## 实时验证究竟做了什么 对于每种带有验证器的密钥类型,`andas` 会向**该凭证自身的提供商发送一个只读请求**(例如 `GET api.github.com/user`)并读取 HTTP 状态码:`2xx` = 有效,`401/403` = 失效。它永远不会执行写入操作,也绝不会将密钥发送到除其合法提供商之外的任何地方。使用 `--no-validate` 可进行完全离线的扫描。 目前支持的验证器:GitHub(PAT + OAuth/App token)、GitLab、Slack、Stripe、npm、SendGrid、Telegram、OpenAI、DigitalOcean、Mailgun,以及配对的验证器 —— **AWS**(一个 `AKIA…` 密钥 + 一个邻近的密钥,通过签名的 STS `GetCallerIdentity` 进行验证)和 **Twilio**(一个 `AC…` SID + 一个邻近的 auth token)。 仅检测不验证:Google、私钥块。 **andas 严格保持只读。** 它扫描文件并仅向凭证自身的提供商发出只读请求——它从不编辑你的代码、轮换密钥或创建 PR。它向你展示风险和修复方法;而采取行动的决定权在于你。 除了这些已知的格式外,一种**信息熵启发式算法**可以捕获自定义/内部的密钥:分配给类似密钥名称(`*token*`、`*apiKey*`、`*password*` 等)的高随机性值。这些是无法验证的,因此它们会被报告为 MEDIUM ——如果其中某个属于误报,`--baseline` 可以将其永久屏蔽。 ## 影响范围 — 一个有效的密钥究竟能造成多大的破坏? 一个有效的密钥是致命的,但一个有效的*管理员*密钥则是五星级警报。由于 andas 已经与提供商进行了通信,它会读取凭证的**身份和权限**,并标记出危险项: ``` CRITICAL GitHub Personal Access Token src/ci/deploy.js:8 ghp_••••••yz ▲ VERIFIED LIVE — rotate this credential now identity: octocat 🔓 can access: repo, admin:org, workflow ⚠ HIGH-PRIVILEGE credential — maximum blast radius ``` - **GitHub** → OAuth scopes(`repo`、`admin:org`、`delete_repo` 等) - **GitLab** → personal-access-token scopes(`api`、`sudo` 等) - **SendGrid** → API-key scopes(`mail.send`、管理员权限等) - **AWS** → 身份 ARN 和账户信息,标记为 root/admin - **Stripe / npm** → 拥有完整访问权限的密钥被标记为特权 高权限的有效密钥会排在报告的最顶部——相同的严重性,更大的影响范围。 ## 暴露时间线与攻击路径 另外两个只读信号,能将一堆发现结果列表转化为真实的图景: - **暴露时间线** — 通过 git blame(以及针对历史泄漏的提交日期),andas 会告诉你一个密钥*已经暴露了多久*:`⏱ 暴露约 47 天(自 2025-11-08 起)`。几个月前泄漏的密钥与今天刚添加的密钥,其紧急程度截然不同。 - **攻击路径** — andas 会描述已确认的发现是如何串联起来的: ⚔ attack path • 一个高权限的 AWS (arn:…:root) 有效凭证暴露——攻击者获得了账户访问权。 • 多个有效凭证(AWS、GitHub)同时暴露——一个泄漏的 repo 让攻击者一次性获取所有凭证。 • 一个已从代码中移除的凭证在 git 历史中仍然有效——删除代码行从未轮换过密钥。 每一行都基于 andas 实际验证过的内容——绝非虚构的风险。 ## 依赖扫描 — 多种语言 `andas` 跨生态系统扫描依赖清单,并将每个包与 [OSV.dev](https://osv.dev) 进行交叉比对: | 语言 | 清单文件 | 可达性 | |----------|----------|--------------| | JavaScript / TypeScript | `package.json` + `package-lock.json` / `yarn.lock` | ✅ import 级别 + 使用的符号 | | Python | `requirements.txt` (固定版本) | — 按严重性排序 | | Go | `go.mod` | — 按严重性排序 | | Ruby | `Gemfile.lock` | — 按严重性排序 | | Rust | `Cargo.lock` | — 按严重性排序 | | PHP | `composer.lock` | — 按严重性排序 | JS/TS 支持以下详述的完整可达性分析;其他语言则提供按实际严重性排序的漏洞发现(这些生态系统的可达性支持已列入路线图)。 ## 深入了解可达性 (JS/TS) 对于包含 `package.json` 的项目,`andas` 还会: 1. 读取 `package.json` 和 lockfile —— `package-lock.json` (npm) 或 `yarn.lock` (Yarn v1 **以及** Berry/v2+) —— 以解析确切的完整依赖树。如果没有 lockfile,则回退到直接依赖。 2. 查询 [OSV.dev](https://osv.dev)(免费,无需 API key)以获取每个包的已知漏洞。 3. 解析你的 `.js/.jsx/.ts/.tsx` 源代码,查看你实际 import 了哪些包,然后遍历依赖图计算哪些是**可达的**。不在此集合中的易受攻击包——未使用的传递依赖,或从未打包进你的 React Native 生产环境的开发工具——将被降级为 `LOW`。 可达性处于 **import 级别**(即包是否被触及)。作为迈向函数级别可达性的第一步,`andas` 还会报告**你的代码实际使用了易受攻击包中的哪些 export**(`↳ 你的代码使用了:merge, template`)——作为分类排查的证据。它故意**不**根据这一信号降级:将安全公告映射到确切的函数是不可靠的,而且虚假的“安全”比误报更糟糕。 ## Git 历史密钥扫描 (`--history`) 最棘手的地方。从你最新提交中删除的凭证仍然存活在 git 历史中——而一旦 repo 公开,历史记录也就公开了。使用 `--history`,andas 会扫描**所有分支和提交中的每一个 blob**,并且——因为它会实时验证——会报告真正重要的情况: ``` CRITICAL AWS Access Key ID (in git history) git history @ 4f1a9c2 (Sara N., 2025-11-08) AKIA••••••7Q ▲ removed from HEAD but still recoverable — AWS accepted the key pair — LIVE → fix: Deactivate the key in IAM → Security credentials, then create a fresh pair. ``` 仍处于工作区中的密钥将留给常规的文件扫描;`--history` 仅报告那些**已移除但从未轮换**的密钥。 ## 报告与 CI - `--html ` — 一个独立、支持主题的 HTML 报告,方便分享。 - `--sarif ` — SARIF 2.1.0;每个结果的级别由**真实风险**驱动,因此失效的密钥会显示为提示,而有效的密钥则显示为错误。使用 `github/codeql-action/upload-sarif` 上传它以填充 Security 选项卡。 - `--markdown ` — 紧凑的 PR 评论风格摘要。andas 仅写入文件;发布它(如果你需要的话)是你 CI 的工作——andas 保持只读。 - 每个发现结果都带有具体的**修复**指引(轮换链接、升级目标)。 在 [`examples/github-workflow.yml`](examples/github-workflow.yml) 中提供了一个现成可用的工作流。 ## 开发 ``` go build -o andas . # build go test ./... # run the test suite go vet ./... # static checks ``` 测试套件直接覆盖了安全核心逻辑:真实风险判定表、信息熵精度(必须能抓取真实密钥并拒绝占位符)、npm/Yarn (v1 + Berry) lockfile 解析器、可达性 BFS 算法、影响范围 scope 解析器、基线读写测试(绝不能持久化存储原始密钥材料),以及对 CLI 布线和 git 历史扫描器的端到端测试。 CI 会运行 `vet` + `test`,并且每次推送时都会让 andas 扫描其自身的源代码。 发布历史请参阅 [CHANGELOG.md](CHANGELOG.md)。 ## 状态 `v1.1.0` — **多语言依赖扫描**(JS/TS、Python、Go、Ruby、Rust、PHP)和 **12 个实时密钥验证器**,构建于一个具备影响范围评分、暴露时间线、攻击路径分析、信息熵检测、基线、pre-commit 防护、四种报告格式以及 48 个测试用例的单一真实风险核心之上。严格只读: | 扫描器 | 检测目标 | 区分信号与噪音的上下文 | |---------|---------|------------------------------------------| | **secrets** | 12 种凭证类型 | 跨 8 家提供商的实时验证(包含签名的 AWS STS) | | **deps** | npm/Yarn 漏洞 (v1 与 Berry) | import 可达性 + 你的代码实际调用的受漏洞影响的函数 | | **git-history** | 从 HEAD 中移除的密钥 | 历史记录中**且**仍然有效 | 输出格式:终端、JSON、HTML、SARIF —— 每一种都包含修复建议。 ## 许可证 MIT — 详见 [LICENSE](LICENSE)。
标签:CISA项目, EVTX分析, Go, Maven, Ruby工具, StruQ, 文档结构分析, 日志审计, 暗色界面, 漏洞验证, 聊天机器人