awslabs/ferret-scan

GitHub: awslabs/ferret-scan

一款完全离线的 CLI 敏感数据扫描与脱敏工具,在 PII、密钥和凭证泄露前对其进行检测、评分和格式保留式掩码。

Stars: 36 | Forks: 2

# ferret-scan

ferret-scan

**在敏感数据泄露之前发现并将其脱敏。** 这是一个单二进制 Go CLI(包含内嵌的 Web UI 和 Go 库 —— `pkg/scan` 用于检测,`pkg/redact` 用于脱敏),可以检测您文件和数据流中的 PII、密钥和 IP 标记,然后通过保留格式和上下文感知的置信度评分,就地对其进行脱敏。无运行时依赖。数据绝不离开您的主机。 [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE.txt) [![Go](https://img.shields.io/badge/Go-1.26-00ADD8?logo=go&logoColor=white)](go.mod) [![PyPI](https://img.shields.io/pypi/v/ferret-scan?logo=pypi&logoColor=white&label=PyPI)](https://pypi.org/project/ferret-scan/) [![Homebrew](https://img.shields.io/badge/Homebrew-ferret--scan-FBB040?logo=homebrew&logoColor=white)](https://github.com/awslabs/ferret-scan#install) [![ECR Public](https://img.shields.io/badge/ECR%20Public-ferret--scan-FF9900?logo=amazonaws&logoColor=white)](https://gallery.ecr.aws/awslabs/ferret-scan) [![GitHub stars](https://img.shields.io/github/stars/awslabs/ferret-scan?style=social)](https://github.com/awslabs/ferret-scan) ![ferret-scan demo](https://static.pigsec.cn/wp-content/uploads/repos/cas/11/116e634f5bd81c3a4689c3da271882fd9176419027bd1f2775286c892bd12720.svg) 一条粘贴到日志行中的客户 SSN。一个提交在 diff 中的 AWS 访问密钥。一份归档到 S3 的客服记录。一个附件在工单中带有 EXIF 元数据的 PDF。敏感数据往往顺着系统间的缝隙泄露出去——一旦它落入日志存储或对象桶中,再想将其清理出来代价就非常高昂。**ferret-scan 就是您放置在这些缝隙前的一道防线:** 它会找出敏感数据值,评估每个数据为真实数据的可能性,并将其脱敏,从而让其余的数据继续顺畅流转。 ## 30 秒内体验一下 ``` # 1. 安装 pip install ferret-scan # 2. 扫描文件(默认情况下值会被 HIDDEN — findings 可以安全分享) ferret-scan --file secrets.env # 3. 在一个 pipe 中 redact 一个 stream(redacted text -> stdout, findings -> stderr) echo "card 5500-0000-0000-0004 from jordan@example.com" \ | ferret-scan --stdin --enable-redaction ``` 最后那条命令会将敏感值转换为掩码但保留原有格式的输出: | 之前 | 之后 (`--enable-redaction`) | |---|---| | `card 5500-0000-0000-0004 from jordan@example.com` | `card ****-****-****-0004 from j*****@example.com` | 敏感值在保留原数据格式的同时被掩码化——因此下游工具、测试和日志流水线依然能正常工作。(此处的示例使用的是保留的文档演示值。) ## 为什么选择 ferret-scan - **可据以行动的可信度。** 评分具备上下文感知能力,而非仅仅依靠正则表达式。金融文件中的信用卡评分会高于测试夹具中相同数字的评分,因为引擎会根据文档类型和周边领域环境重新加权。检测结果分为三个等级:**HIGH (90–100)**,**MEDIUM (60–89)**,**LOW (0–59)**。 - **可组合的脱敏方式。** stdin 网关将脱敏后的字节流输出至 stdout,并将检测结果输出至 stderr,因此可以直接接入任何 Unix 管道或 CI 步骤。提供三种策略:`simple`、`format_preserving`(默认)和 `synthetic`(用于构建测试数据集的逼真虚假数据)。 - **可解释性,离线运行。** `--explain` 会为每个检测结果附带一段通俗语言的逻辑说明、判定结果(`likely_real` / `likely_test` / `uncertain`)以及起草的抑制理由。完全确定性——无需网络,也不依赖 LLM。 - **全平台部署。** 单一静态二进制文件,无运行时依赖,提供基于 `scratch` 的 Docker 镜像(约 5–10 MB)、`pip` 包、Homebrew tap、pre-commit hook 以及稳定的 Go 库(`pkg/scan` + `pkg/redact`)。 - **设计上保障安全。** 除非您传入 `--show-match`,否则匹配到的值将被隐藏。内存中的脱敏过程会生成不含实际载荷的审计记录。Web UI 绑定至 `127.0.0.1`,并具有 CSRF 和 CSP 防护。 ## 安装 选择适合您工作流的方式即可——它们均是一等支持。 | 方式 | 命令 | |---|---| | **Homebrew** (macOS/Linux) | `brew tap awslabs/ferret-scan https://github.com/awslabs/ferret-scan && brew install awslabs/ferret-scan/ferret-scan` | | **pip** (CLI + pre-commit) | `pip install ferret-scan` | | **Docker** | `docker pull public.ecr.aws/awslabs/ferret-scan:latest` | | **源码安装** (Go 1.26.5) | `git clone https://github.com/awslabs/ferret-scan.git && cd ferret-scan && go build ./cmd` | Docker 一行命令(挂载当前目录并进行扫描): ``` docker run --rm -v "$PWD:/data" public.ecr.aws/awslabs/ferret-scan:latest --file /data --recursive ``` ## 检测内容 共有 19 个专门的验证器。使用 `--checks CREDIT_CARD,SECRETS,SSN` 启用部分检测,或全部启用(默认)。 | 验证器 | 识别内容 | 备注 | |---|---|---| | `CREDIT_CARD` | 15+ 个品牌的信用卡号 | Luhn 校验;发出 `VISA`, `MASTERCARD`, `AMERICAN_EXPRESS`, …;过滤已知的测试模式 | | `SECRETS` | API key、token、credential | 熵分析 + 40+ 种模式 (AWS key, GitHub token, Stripe, …) | | `SSN` | 美国社会安全号码 | 领域感知 (HR / 税务 / 医疗保健上下文) | | `BANK_ACCOUNT` | 汇款路线号码、IBAN、SWIFT/BIC | ABA 校验和,IBAN mod-97,SWIFT 格式;发出 `ABA_ROUTING`, `IBAN`, `SWIFT_BIC`, `US_BANK_ACCOUNT` | | `OTP` | 2FA secret 和恢复代码 | `otpauth://` URI,TOTP/HOTP secret (base32),恢复代码块;发出 `OTPAUTH_URI`, `OTP_SECRET`, `RECOVERY_CODES` | | `DATE_OF_BIRTH` | PII 上下文中的出生日期 | 非常保守——需要 DOB 关键字;无上下文的日期评分 <30 | | `PHYSICAL_ADDRESS` | 美国街道地址 | 需要街道类型后缀;发出 `US_STREET_ADDRESS`, `PO_BOX` | | `DRIVERS_LICENSE` | 美国驾驶证号码 | 特定州格式(前 10 个州);依赖关键字以避免误报 | | `MEDICAL_ID` | 医疗保健标识符 | NPI (Luhn 校验)、DEA (校验和)、MRN、保险 ID、Medicare MBI | | `EMAIL` | 电子邮件地址 | 已知 SaaS/企业域名发出 `BUSINESS` | | `PHONE` | 电话号码 | 国际格式 | | `IP_ADDRESS` | IPv4 / IPv6 地址 | 跳过 RFC1918 / 保留 / 测试网段;由上下文关键字控制 | | `PASSPORT` | 护照号码 | 美国 / 英国 / 加拿大 / 欧盟 + MRZ | | `VIN` | 车辆识别代号 | ISO 3779,第 9 位校验位,WMI 制造商查询 | | `PERSON_NAME` | 个人姓名 | 内置姓名数据库、称谓、文化变体 | | `CLOUD_RESOURCES` | 云资源标识符 | AWS ARN、Azure ID、GCP、OCI、IBM CRN、阿里云 | | `INTELLECTUAL_PROPERTY` | IP / 机密标记 | 专利、商标、版权、商业机密 | | `SOCIAL_MEDIA` | 社交媒体账号 / 个人资料 | 需要配置才能激活 | | `METADATA` | EXIF / 文档元数据 | 仅限文件路径(需要文件系统);通过 CLI 和 `pkg/scan.ScanFile` 提供,不支持 `ScanText`/`pkg/redact`(内存中) | ## 示例输出 默认情况下,匹配的值会被**隐藏**——该报告可以安全地粘贴到工单中或与同事分享。 ``` LEVEL VALIDATOR TYPE CONF% LINE MATCH FILE [HIGH ] ssn SSN 100.00% line 3 [HIDDEN] demo.txt [HIGH ] email BUSINESS 100.00% line 1 [HIDDEN] demo.txt [HIGH ] secrets AWS_ACCESS_KEY 100.00% line 4 [HIDDEN] demo.txt [MEDIUM] phone PHONE 75.00% line 3 [HIDDEN] demo.txt ``` 传入 `--show-match` 可显示其背后的真实值,传入 `--explain` 可查看每个结果被标记的*原因*。 ### 输出格式 使用 `--format` 选择格式: `text` (默认) · `json` · `csv` · `yaml` · `junit` · `gitlab-sast` · `sarif` `sarif`、`gitlab-sast` 和 `junit` 格式可直接接入 GitHub 代码扫描、GitLab SAST 报告和 CI 测试仪表板。 ## 运行方式 **扫描文件、目录和 glob 匹配** ``` ferret-scan --file ./src --recursive ferret-scan --file "logs/*.txt" --checks SECRETS,CREDIT_CARD ferret-scan --file report.pdf --explain --format json --output findings.json ``` **对数据流进行脱敏**(可在管道中组合使用;脱敏后的字节流输出至 stdout,检测结果输出至 stderr) ``` cat customer-export.csv | ferret-scan --stdin --enable-redaction --redaction-strategy synthetic > safe-export.csv ``` **pre-commit hook** —— 在密钥提交前拦截它们 ``` # .pre-commit-config.yaml repos: - repo: https://github.com/awslabs/ferret-scan rev: v1.10.0 hooks: - id: ferret-scan ``` **CI/CD** —— 输出 SARIF 或 GitLab SAST 报告 ``` ferret-scan --file . --recursive --format sarif --output ferret.sarif --quiet ``` **容器** —— 无需本地安装即可扫描挂载的目录 ``` docker run --rm -v "$PWD:/data" public.ecr.aws/awslabs/ferret-scan:latest --file /data --recursive ``` **Web UI** —— 文件夹拖拽和批量抑制管理 ``` ferret-scan --web --port 8080 ``` **Go 库** —— 在进程内嵌脱敏(见下文)。 ## Web UI 启动一个采用 CloudScape 风格的本地界面,进行交互式扫描、文件夹拖放以及批量抑制管理: ``` ferret-scan --web ``` 它默认绑定至 `127.0.0.1`(仅在容器内自动检测并使用 `0.0.0.0`),强制执行 CSRF/Origin 检查,并发送 CSP 头。要将其暴露在您的局域网中,请传入 `--bind 0.0.0.0` ——请注意该 UI 没有身份验证,因此仅限在受信任的网络中执行此操作。 ![ferret-scan web UI — main interface](https://static.pigsec.cn/wp-content/uploads/repos/cas/55/55c87f49bfc04a7495db99ba96923be8c6c4c2b880013104ded3a847df4f5079.png) ![ferret-scan web UI — scan results](https://static.pigsec.cn/wp-content/uploads/repos/cas/19/190083aee7e08c1552fbf8e3f71996130cb4b231197ff1b0217e37a62b27f470.png) ## 将其嵌入:Go 库 两个公开 package 让您可以将 ferret-scan 嵌入到您的 Go 应用程序中——无需子进程,无需 CLI,也不会发生载荷泄露: | Package | 用途 | 输入 | |---|---|---| | **`pkg/scan`** | **检测** —— 查找敏感数据 | 文本字符串或文件路径 | | **`pkg/redact`** | **脱敏** —— 掩码/替换检测结果 | 文本字符串(基于 Engine,通过一次调用即可完成检测+脱敏) | 检测和脱敏是**独立的关注点**——您可以只使用其中一个,也可以同时使用: ### 仅检测 (`pkg/scan`) ``` import "github.com/awslabs/ferret-scan/v2/pkg/scan" // In-memory text detection (no disk, no temp files) result, _ := scan.ScanText(ctx, "card 5500-0000-0000-0004", scan.TextOptions{ Checks: []string{"CREDIT_CARD", "SSN"}, Explain: true, // attach "why flagged" rationale }) for _, f := range result.Findings { fmt.Printf("%s (line %d, %s, %s)\n", f.Type, f.LineNumber, f.Band(), f.Rationale) } // File-based detection (PDF, DOCX, XLSX, images, text — 90+ types) result, _ = scan.ScanFile(ctx, "report.docx", scan.FileOptions{}) // Check if a file type is supported before scanning ok, reason := scan.CanProcessFile("archive.zip") // false, "Unsupported file type" // Redact text in-place using pre-computed findings (no re-detection) redacted, _ := scan.RedactText(text, result.Findings, scan.StrategyFormatPreserving) // Redact a file (writes a redacted copy of the same type: .docx→.docx, .pdf→.pdf) fileResult, _ := scan.RedactFile("report.docx", scan.RedactFileOptions{ OutputDir: "/tmp/redacted", Strategy: scan.StrategyFormatPreserving, }) ``` `pkg/scan` 暴露了:`ScanText`, `ScanFile`, `RedactText`, `RedactFile`, `CanProcessFile`, `CheckNames`, `ConfidenceOf`, `ParseStrategy`。所有这些都会零重复地委托给内部引擎。 ### 通过一次调用完成检测+脱敏 (`pkg/redact`) 当您希望在**单步中同时完成检测和脱敏**并使用可复用、预加载的引擎时,`pkg/redact` 是更高层级的 API。`Engine` 只构建一次并被复用;它是并发安全的。 ``` import "github.com/awslabs/ferret-scan/v2/pkg/redact" engine, _ := redact.NewEngine(redact.EngineOptions{ Checks: []string{"CREDIT_CARD", "EMAIL"}, Strategy: redact.FormatPreserving, }) defer engine.Close() result, _ := engine.Redact(ctx, redact.Request{ Text: "card 5500-0000-0000-0004 from jordan@example.com", Label: "req-abc-123", }) log.Println(result.Redacted) // ****-****-****-0004 from j*****@example.com log.Printf("%+v", result.AuditRecord()) // payload-free audit summary ``` `Result.AuditRecord()` 返回一条不含实际载荷的记录——包含按类型统计的发现数量、字节数、持续时间——**绝不**包含匹配的字节。`LogWriter` 默认为 `io.Discard`,因此在构造层面就强制执行了不泄露的特性。匹配的子字符串只能通过显式选择开启(`Result.FindingsWithMatchText()`)来获取。输入限制为 100 MB。 ### 构建一个 PII 脱敏网关 由于这两个 package 完全在内存中运行——没有子进程,不涉及文件系统,且生成不含载荷的审计记录——您可以构建一个单租户脱敏服务,而 ferret-scan 绝不会将敏感字节写入磁盘或日志中。一个具有代表性的架构形态如下: - 将 `Engine` 嵌入到 **AWS Lambda**(`provided.al2023`,`arm64`)中,在 `init()` 中构造一次并在多次调用中复用。 - 在其前端部署一个 **API Gateway HTTP API**,并使用 IAM (SigV4) 身份验证。 - 调用方 `POST` 一段 JSON `{ "text": "...", "strategy": "format_preserving" }` 并接收返回 `{ "redacted": "...", "request_id": "...", "duration_ms": }`。 - **CloudWatch** 仅记录审计**计数**——绝不记录载荷字节——因为 `AuditRecord` 不包含任何匹配的子字符串。 - 网关限流机制可防范滥用和 DoS。 这是公共 API 所支持的一种架构;ferret-scan 本身提供 CLI、Web UI 和库——但不提供网关本身。请注意, 同步调用将请求体限制在 ~6 MB 以内。 ## 安全态势 - **默认隐藏数据值。** 检测结果绝不包含匹配的文本,除非您传入 `--show-match` (CLI) 或显式调用 `Result.FindingsWithMatchText()` (库)。 - **无载荷审计记录。** 库的 `AuditRecord` 只报告计数、大小和时间——绝不包含敏感字节。 - **内存擦除。** 敏感缓冲区使用带有多次清零的 `SecureString`(属于 MEDIUM 安全态势,受限于 Go 运行时所允许的操作范围)。 - **抑制系统。** 基于规则的误报管理,在 Web UI 中支持批量操作,让您无需编辑源代码即可调整信号。 - **加固的 Web 服务器。** 默认绑定 `127.0.0.1`,执行 CSRF/Origin 检查,并设置 CSP 头。 了解完整的模型——信任边界、威胁和缓解措施——请参见 **[THREAT_MODEL.md](THREAT_MODEL.md)**。 ## 文档 | 主题 | 链接 | |---|---| | 完整文档索引 | [docs/README.md](docs/README.md) | | 配置与 profiles | [docs/configuration.md](docs/configuration.md) | | 威胁模型 | [THREAT_MODEL.md](THREAT_MODEL.md) | | 编写自定义验证器 | [docs/development/creating_validators.md](docs/development/creating_validators.md) | ## 许可证 Apache-2.0。版权所有 Amazon.com, Inc. 或其附属公司。一个 [awslabs](https://github.com/awslabs) 开源项目——欢迎贡献。请参阅 [LICENSE.txt](LICENSE.txt)。
标签:EVTX分析, Go, Ruby工具, StruQ, 敏感数据检测, 数据脱敏, 日志审计, 本地安全, 网络安全, 请求拦截, 逆向工具, 隐私保护