Indegosblade/HYGEIA

GitHub: Indegosblade/HYGEIA

HYGEIA 是一款零依赖的跨平台取证级 PII 净化引擎,通过 schema 感知处理器和失败即关闭验证机制,在保留结构化数据的同时精准清除设备转储中的个人身份信息。

Stars: 0 | Forks: 0

# HYGEIA [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/Indegosblade/HYGEIA/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/Indegosblade/HYGEIA/branch/main/graph/badge.svg)](https://codecov.io/gh/Indegosblade/HYGEIA) [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/) [![Platform](https://img.shields.io/badge/platform-linux%20%7C%20macOS%20%7C%20windows-lightgrey.svg)](https://github.com/Indegosblade/HYGEIA/actions/workflows/ci.yml) [![License: PolyForm](https://img.shields.io/badge/license-PolyForm%20NC-green.svg)](LICENSE) 真正理解数据内容的取证级 PII 净化工具。 21 个具备 schema 感知能力的处理器可通过表签名(而非盲目猜测文件名)检测并精准清除 Chrome 配置、Firefox 数据库、iOS 文件系统转储、Android 提取数据以及 Windows 取证工件。作为安全兜底,其余所有内容均会经过全面的 regex + 列名扫描。零外部 pip 依赖。 **已在内部测试的平台:** Chrome/Chromium(4 个处理器) · Firefox(3 个) · iOS(10 个) · Android(3 个) · Windows(1 个 + 文件系统规则) · macOS · Linux **合规性:** HIPAA Safe Harbor · GDPR 第 4/9 条 · CCPA — 附带单次运行的覆盖率报告。 **验证机制:** 失败即关闭(fail-closed) — 只有当 PII 检出数为零**且**所有检查均切实完整运行时,运行结果才会被报告为 PASSED。如果遇到工具缺失、数据库被锁定、文件过大,或由于使用 `--only`/`--skip-patterns` 缩小了范围,HYGEIA 将会以非零状态码退出并明确告知原因,绝不会盲目判定为“已清理”。 ## 为什么选择 HYGEIA? 现有的工具要么做不到这一点,要么解决的是不同的问题: - **Cellebrite UFED / Magnet AXIOM / EnCase** — 价值 1.5K 到 5 万美元/席位的专业取证*采集*工具。它们负责提取和展示 PII,但不会将其删除。如果你需要在不泄露个人数据的情况下共享数据转储,这些工具无能为力。 - **Autopsy** — 免费的取证分析工具。同样的问题:它能发现 PII,但无法进行净化。不存在所谓的“打码并导出干净数据”的工作流。 - **手动修改 SQLite** — 会遗漏 WAL 文件(其中包含 50%-95% 的“已删除”记录)、空闲列表页(freelist pages)、FTS 影子表、LevelDB 和缩略图缓存。只要漏掉一个工件,数据就能被恢复。 - **通用的 regex 清洗工具** — 不懂数据库 schema。无法区分 Chrome 的 Login Data 表和 Firefox 的 permissions 表。无法执行 WAL checkpoint 或 VACUUM。无法处理特定平台的列语义。 HYGEIA 的诞生是因为没有其他任何工具能在单次处理中,将具备平台感知能力的精准净化与反取证强化结合起来。它专为需要共享设备转储的安全研究人员、准备法庭证物的取证分析师、需要净化测试数据的红队,以及处理 DSAR 请求的合规团队而构建 — 适用于任何需要保留结构数据同时去除个人数据的场景。 ## 安装 ``` pip install git+https://github.com/Indegosblade/HYGEIA.git ``` 环境要求:Python 3.10+。可选:[exiftool](https://exiftool.org/)(用于剥离图像元数据)。 ## 用法 ``` # 标准脱敏 hygeia --input /path/to/data --output /path/to/clean # 预览而不修改任何内容 hygeia --input /path/to/data --output /unused --dry-run # 符合 HIPAA 的脱敏 hygeia --input /path/to/data --output /path/to/clean --compliance hipaa # 最大力度脱敏:所有 compliance frameworks + timestamp normalization hygeia --input /path/to/data --output /path/to/clean --compliance all --normalize-timestamps # 带有自定义 manifest 路径的 verbose output hygeia --input /path/to/data --output /path/to/clean -v --manifest audit.json ``` ### 模式选择 ``` # 仅移除图像元数据(EXIF GPS、device identifiers) hygeia --input /path/to/data --output /clean --only exif # 仅检测 VINs 和 credit cards hygeia --input /path/to/data --output /clean --only vin,credit_card # 运行除 crypto wallet detection 之外的所有内容 hygeia --input /path/to/data --output /clean --skip-patterns crypto # 仅运行 identity + financial patterns(无 credentials、无 location、无 healthcare) hygeia --input /path/to/data --output /clean --only identity,financial # 列出所有可用类别和 patterns hygeia --list-patterns ``` ### 参数标志 | 标志 | 描述 | |------|-------------| | `--input PATH`, `-i` | 源数据目录 | | `--output PATH`, `-o` | 净化后副本的输出目标 | | `--dry-run`, `-n` | 预览所有操作但不实际执行 | | `--compliance MODE` | 合规模式:`hipaa`、`gdpr`、`ccpa` 或 `all` | | `--only PATTERNS` | 专门激活的、以逗号分隔的类别或模式名称 | | `--skip-patterns PATTERNS` | 需要排除的、以逗号分隔的类别或模式名称 | | `--list-patterns` | 打印所有可用的类别和模式,然后退出 | | `--normalize-timestamps` | 将所有文件时间戳设置为 epoch(以对抗时间线分析) | | `--skip-verify` | 跳过净化后的验证 | | `--skip-exif` | 跳过 EXIF 元数据剥离 | | `--skip-forensic` | 跳过反取证强化(LevelDB、缓存、交换分区、时间戳) | | `--manifest PATH`, `-m` | JSON 审计清单的自定义路径 | | `--verbose`, `-v` | 详细日志记录 | | `--workers N`, `-w` | 用于独立净化任务的并行工作线程数。`1` = 顺序执行(默认),`0` = 自动检测(`os.cpu_count()`),`>1` = 显式指定线程池大小 | ### 退出码 | 代码 | 含义 | |------|---------| | 0 | 净化完成,验证通过(或被跳过) | | 1 | 输入错误(未找到路径、输出目录已存在) | | 2 | 验证失败 — 检测到残留 PII,和/或验证无法证明转储数据已清理干净(缺少 exiftool、数据库被锁定/不可读/加密、文件过大,或由于缩小了 `--only`/`--skip-patterns` 范围)。当无法提供确凿保证时,HYGEIA 绝不会以 0 退出。 | ## 处理流水线 HYGEIA 每次执行时都会运行一个确定性的 7 阶段流水线: ``` [1/7] Scan Classify every file by type. Auto-detect iOS or generic mode. [2/7] Databases Platform detection → WAL-checkpoint → secure_delete → regex scan → table nuke → FTS rebuild → VACUUM [3/7] Text files Redact PII in JSON, logs, CSV/TSV. Delete shell history files. [4/7] Forensics Delete LevelDB stores, thumbnail caches, swap files, search indexes, session data. [5/7] Media Strip EXIF from images, metadata from PDFs (author/creator/producer/XMP), Office docs (docx/xlsx/pptx properties + tracked-changes/comment authors). [6/7] Verify Read-only, fail-closed scan: every row and column (incl. BLOB) of every surviving database, plus every text file, checked for residual PII. Anything that couldn't be checked to completion is recorded as incomplete, never assumed clean. [7/7] Manifest Write JSON audit trail: actions taken, verification result, compliance report. ``` 该流水线采用失败即关闭机制:如果验证过程发现了残留 PII — 或者由于某些检查未能完整运行而无法证明输出是干净的 — HYGEIA 将以退出码 2 退出,并准确报告发现了什么、哪些内容无法检查以及位置所在。一次通过的运行意味着在所有扫描的内容中 PII 检出数为零,**且**没有不完整的检查。 ## 检测内容 所有模式都存放在单一的 JSON 真理源(`hygeia/rules/pii_patterns.json`)中,并按可选类别进行组织。每个模式都可以通过 `--only`/`--skip-patterns` 按类别或单独激活。 ### 模式类别 | 类别 | 模式数 | 示例 | |----------|----------|----------| | **身份信息** | 17 | 电子邮件、美国/国际电话、SSN、英国 NIN、印度 PAN/Aadhaar、美国 ITIN、巴西 CPF、墨西哥 CURP、韩国 RRN、加拿大 SIN/澳大利亚 TFN、日本 My Number、IMEI、IMSI、设备名称、Apple ID | | **位置信息** | 4 | GPS 坐标(包括小于 1 度的值,如 `-0.1278`)、IPv4、IPv6(完整 + 压缩 `::` 表示法)、MAC 地址 | | **财务信息** | 7 | 信用卡(包括带空格/连字符的 Amex)、IBAN、SWIFT/BIC、美国 EIN、美国路由号码、CUSIP、ISIN | | **凭证信息** | 18 | JWT token、AWS 访问密钥、GitHub/GitLab token、Slack token、Stripe/OpenAI/Twilio/SendGrid 密钥、npm/PyPI/Docker/DigitalOcean/Shopify token、Telegram bot token、通用 API 密钥、URL 中嵌入的凭证、私钥标头 | | **加密货币** | 7 | Bitcoin(legacy + bech32)、Ethereum、Litecoin、Ripple,以及 Monero/Solana/Cardano(视上下文而定) | | **医疗保健** | 4 | NPI(独立 + 上下文)、DEA 编号、Medicare MBI、NDC(国家药品代码) | | **车辆信息** | 2 | VIN(17 字符 ISO 3779)、英国车牌号 | 上述模式是默认开启的、基于内容的 regex(共 59 个)。另有 9 个上下文限制模式(见下文)仅会在附近出现确认关键字时触发 — 例如,美国护照和驾驶证号码位于此处,而不是身份信息类别中,因为一串简短的纯数字序列过于模糊,不适合直接标记。 ### 上下文相关模式 这些模式仅会在附近的确认关键字支持上下文时触发 — 短数字序列(9-10 位数字)、key=value 对以及类似 base64 编码的字符串如果仅凭内容判断过于模糊,不适合直接标记。它们在两个方向上保持一致应用:在净化期间(JSON/log/CSV 脱敏)和在验证期间(残留 PII 扫描),因此匹配项的脱敏方式与将其标记为残留发现项的方式完全相同: | 模式 | 需要的关键字 | 窗口范围 | |---------|-------------------|--------| | 美国护照 | "passport" | 120 字符 | | 驾驶证 | "license", "dl", "driver" | 120 字符 | | 加拿大 SIN | "sin", "social insurance" | 120 字符 | | 澳大利亚 TFN | "tfn", "tax file" | 120 字符 | | 美国路由号码 | "routing", "aba", "bank" | 120 字符 | | 出生日期 | "dob", "birth", "birthday" | 200 字符 | | 密码 (key=value) | "password", "passwd", "pwd" | 200 字符 | | AWS 密钥 | "aws", "secret", "AWS_SECRET" | 120 字符 | | NPI | "npi", "provider", "prescriber" | 120 字符 | ### 列名检测 超过 150 个列名被视为天生敏感 — 任何非空值都会被替换为 `[REDACTED]`: `email`、`username`、`password`、`phone`、`address`、`street`、`city`、`zip`、`first_name`、`last_name`、`full_name`、`ssn`、`credit_card`、`latitude`、`longitude`、`api_key`、`token`、`cookie`、`session`、`encrypted_value`、`ip_address`、`remote_addr`、`mac_address`、`device_id`、`udid`、`serial_number`、`imei`、`account_number` 等等。 JSON/plist 键名检测还额外识别专用的 `address` 类别(`street`、`city`、`zip`、`postal_code`、`employer`、`organization` 等)以及 iOS CoreData 位置列(`ZLATITUDE`、`ZLONGITUDE`、`ZLOCATION`、`ZALTITUDE`、`ZCOORDINATE`)。CoreData 命名还驱动了 plist 中 **float** 和与位置提示相关的整数值中的 GPS 检测(例如以 `` 格式存储的 `lastKnownLatitude`),这些以前无论键名如何都不会被处理。 ### 表级彻底清除 跨平台的 80 多个表名 — 删除所有行,保留 schema: ## 平台覆盖范围 下面列出的每个平台都附带了经过测试的处理器 — 而非理论上的覆盖。自动检测基于表签名(schema 检查),而不是依赖文件名或目录路径。 ### Chrome / Chromium(4 个处理器) History、Login Data、Web Data、Cookies、Shortcuts、Top Sites、Favicons、DIPS、Network Action Predictor、Extension Cookies、Affiliation Database、Media History。通过表签名自动检测 — Login Data 的清除方式与 History 不同。LevelDB localStorage 和 IndexedDB 目录将被删除。包含会话数据清理。 ### Firefox(3 个处理器) places.sqlite、cookies.sqlite、formhistory.sqlite、permissions.sqlite、content-prefs.sqlite、key4.db、cert9.db、signons.sqlite、webappsstore.sqlite。通过 `moz_*` 表的存在自动检测。IndexedDB 存储目录将被删除。会话恢复文件将被删除。包含缓存清理。 ### iOS(10 个处理器) Messages、Photos.sqlite、Health、Contacts、Safari History/Bookmarks、Notes、knowledgeC、Screen Time、TCC.db。支持越狱感知扫描,动态检测 Dopamine、palera1n 和 RootHide。在保留越狱基础架构(`/var/jb/`、`/private/preboot/`、包数据库)的同时移除用户数据。对 knowledgeC.db 进行列级净化(脱敏第三方应用名称,保留系统应用使用情况),以及 Photos.sqlite(将 GPS 坐标设为 NULL,删除面部识别数据 — 现在的检测能正确匹配 iOS 14 之前(`ZGENERICASSET`)和 iOS 14+(`ZASSET`)的 schema,两者中存在任意一种即足以触发匹配)。删除 SEGB biome 流。包含带 WAL 处理的第三方容器清理。 ### Android(3 个处理器) contacts2.db、mmssms.db、telephony.db、calendar.db、accounts.db、webview.db。删除缩略图缓存。删除 Google Analytics 数据库。 ### Windows(1 个处理器 + 文件系统规则) WebCacheV01.dat 基于 ESE,而非 SQLite — Python 无法原生解析 ESE,因此该文件由扫描器的 delete-pattern 匹配直接删除,而不是在原地净化(`windows_webcache` SQL 处理器的存在是为了应对极少数在 SQLite 格式中出现具有匹配表名的数据库的情况,但真正的 WebCacheV01.dat 永远不会走到这一步)。其他覆盖范围包括:预读取文件 (.pf)、跳转列表、LNK 文件、事件日志、回收站标记($I/$R 文件)、交换/休眠文件(pagefile.sys、swapfile.sys、hiberfil.sys)、缩略图缓存。 ### macOS TCC.db 权限授予、隔离事件数据库、Spotlight 索引(.Spotlight-V100)、FSEvents 日志(.fseventsd)、Shell 历史记录文件、Accounts 数据库、统一日志追踪。 ### Linux Shell 历史记录文件(.bash_history、.zsh_history、.python_history 等)、GNOME Tracker 数据库、缩略图缓存、systemd journal 工件。 ### 通用处理(针对任何无法识别的数据库的兜底方案) 任何包含 SQLite 数据库的目录:HYGEIA 会扫描每个表中的每一列 — 无论声明的类型是什么,包括以字节形式存储文本的 BLOB/INTEGER/REAL 列 — 以查找 PII 模式,无需任何特定平台的知识。这就是我们的安全网 — 如果你的数据库不属于已识别的 20 种类型,它依然会被净化。 ## 合规性 ### HIPAA Safe Harbor (45 CFR 164.514(b)(2)) `--compliance hipaa` 标志会激活对全部 18 种 Safe Harbor 标识符的检测:姓名、州级别以下的地理分区、日期(除年份外)、电话号码、传真号码、电子邮件地址、Social Security 号码、医疗记录号码、健康计划受益人号码、帐号、证书/执照号码、车辆标识符、设备标识符、Web URL、IP 地址、生物识别标识符、照片以及唯一代码。每次运行都会根据净化器实际生成的凭证(脱敏列、清除表、regex 匹配命中)评估所有 18 项 — 只有在有确凿证据时,标识符才会被报告为 `covered`;否则就是一个 `gap`(失败即关闭:证据缺失绝不会被静默视为已移除)。 Safe Harbor 还要求将日期概括为年份,将 ZIP code 截断为 3 位数字(对于 HHS 列出的人口稀少前缀设为 `000`)。`generalize_date()`/`truncate_zip()` 实现了这些转换,并通过 `ComplianceProfile.transform_value()` 串联起来,但运行中的流水线本身只根据名称净化出生日期/ZIP code *列* — 它不会重写在其他地方发现的自由文本日期或 ZIP code。单次运行报告会在 `limitations` 条目中清楚说明这一点,而不是让一个 `covered` 的日期/地理位置结果暗示执行了超出实际范围的操作。 ### GDPR 第 4/9 条 `--compliance gdpr` 标志增加了对第 9 条中定义的特殊类别数据的检测:种族/民族本源、政治观点、宗教信仰、工会会员资格、基因数据、生物特征数据、健康数据和性取向。列名检测扩展了诸如 `race`、`ethnicity`、`religion`、`political_opinion`、`genetic_data`、`health_data` 等术语。与 HIPAA 一样,GDPR 模式报告每个标识符的真实 `covered`/`gaps`(以前只报告框架名称而背后没有覆盖细节)。特殊类别检测仅基于列名 — 不会检测 notes/bio/message 列中的自由文本特殊类别数据,报告会通过常驻 `limitations` 条目和显式的 `free_text_special_categories` 缺口说明这一点。 ### CCPA `--compliance ccpa` 标志将浏览历史记录、搜索历史记录、地理位置数据以及购买/交易记录视为强制删除类别,这反映了 CCPA 对个人信息的宽泛定义(包括行为和商业数据)。与 GDPR 一样,CCPA 模式报告标识符级别的覆盖率/缺口,而不是仅给出光秃秃的框架标签,并会在 `delete_browsing_history` 请求在特定转储中未找到匹配的表进行删除时予以明示。 ### 组合模式 `--compliance all` 应用所有框架的并集 — 这是可用的最严格的净化配置。 每次合规运行的报告 — 无论什么模式 — 都包含 `identifiers_covered`、`gaps` 和 `limitations` 列表。被命名的框架(`HIPAA Safe Harbor` 等)永远只是一个标签;这三个字段是对每个数据集实际交付内容的诚实记录,如果没有来自该运行的确凿证据,任何内容都不会被标记为 `covered`。 ## 反取证强化 HYGEIA 旨在生成能够经受包括 Cellebrite UFED、Autopsy、EnCase 和 Magnet AXIOM 在内的取证工具审查的输出。 | 技术 | 对抗目标 | |-----------|----------------| | WAL checkpoint + 伴随文件删除 | 针对已删除记录的 WAL 文件雕刻 | | `PRAGMA secure_delete = ON` | 活动数据库页内的已删除单元格恢复 | | VACUUM 重建(失败会显现,绝不静默) | 针对未分配数据库页的空闲列表页雕刻 | | FTS3/4/5 影子表重建 — 遇到结构上无内容/外部内容表时失败即关闭 | 全文搜索索引数据恢复(`*_content`、`*_segments`、`*_data`、`*_idx`) | | unlink 前进行随机字节覆写(数据库 + WAL/SHM/journal 伴随文件) | 针对未分配磁盘块中已删除数据库字节的取证雕刻 | | LevelDB 目录删除 | Chrome localStorage/IndexedDB 内容雕刻 | | 缩略图缓存删除 | 源文件删除后缩略图的持久化 | | 交换/休眠文件删除 | 从 pagefile.sys、hiberfil.sys 中恢复 RAM 工件 | | Shell 历史记录删除 | 命令行凭证和活动恢复 | | Spotlight/搜索索引删除 | 已索引的文档内容恢复 | | 时间戳标准化(支持 symlink 安全 — 绝不跟随转储之外的链接) | MACB 时间线重建和活动相关性分析 | ## 验证 每次净化运行都包含自动验证(可通过 `--skip-verify` 禁用)。验证采用**失败即关闭**机制:当它无法切实证明转储是干净的时候,绝不会报告该转储已清理干净 — 缺少工具、数据库锁定或缩小模式选择范围,都会像残留 PII 匹配一样阻碍得到 PASSED 结果。 1. **内容扫描**:每个存活的文本文件,以及每个 SQLite 数据库的完整内容 — 所有表、无论声明类型是什么的所有列(TEXT/BLOB/INTEGER/REAL)、所有行、没有行数上限 — 都会被 regex 扫描以查找完整的 PII 模式集合。BLOB/bytes 单元格在进行匹配之前会经过 UTF-8 解码,因此存储在二进制类型列中的 PII 依然会被捕获。数据库严格以只读模式(`mode=ro`)打开;验证过程绝不会写入、VACUUM 或以其他方式更改它正在检查的工件。 2. **空闲列表检查**:每个 SQLite 数据库以只读方式打开,并检查是否存在非零的空闲列表页数。任何非零的空闲列表始终被报告为一项发现 — 验证器不再尝试自行执行 VACUUM 并在该 VACUUM 被锁阻止时静默放弃该发现(这曾发生在例如“Login Data”上的 Chrome WAL 锁的情况中)。 3. **EXIF 检查**:验证图像是否包含残留的 GPS 坐标和设备标识符标签 — 但仅在安装了 exiftool 的情况下执行。如果缺少该工具,图像既不会被剥离也不会被验证,现在这会被报告为**不完整**的检查,而不是静默的、不劳而获的通过。 4. **误报过滤**:URL 列、系统框架路径和已脱敏的值将被排除,以防止干扰。 一次运行会以下列三种状态之一结束: - **PASSED** — 零项 PII 发现,零项空闲列表发现,零项 EXIF 失败,并且每项检查都完整运行完毕。退出码 0。 - **FAILED(发现项)** — 一项或多项残留的 PII、空闲列表或 EXIF 发现。退出码 2。 - **FAILED(不完整)** — 每一项*切实*运行的检查均未发现任何问题,但至少有一项检查完全无法完成:缺少 exiftool、数据库被锁定/损坏/加密且无法读取、文件或数据库太大无法扫描,或者是 `--only`/`--skip-patterns` 的运行缩小了检查的类别。HYGEIA 会确切打印出哪些检查未完成及其原因,并以退出码 2 退出 — 当无法提供支持时,它绝不会打印出“PASSED”。 `--only`/`--skip-patterns` 运行还会附带一个**范围**注解:由于它仅检查了选定的类别,通过将被报告为“仅针对限定范围类别 (...) 通过 — 并非完整的无污染证明”,绝不会作为毫无保留的合格证明。 验证失败时,会报告每一项发现的具体文件、表、列、行和匹配的模式 — 以及每一项不完整项目的具体检查、路径和原因。 ## 编程 API ``` from pathlib import Path # 通用数据库脱敏 from hygeia.sqlite_sanitizer import sanitize_database_generic result = sanitize_database_generic(Path("any_database.db")) print(f"Redacted {result['rows_redacted']} rows, found: {result['pii_types_found']}") # => 已脱敏 847 行,发现:['email', 'phone', 'sensitive_column:username'] # 感知平台的数据库脱敏(自动检测 Chrome、Firefox、iOS 等) from hygeia.platform_handlers import sanitize_with_platform_detection result = sanitize_with_platform_detection(Path("Login Data")) print(f"Platform: {result.get('platform', 'generic')}, deleted: {result['rows_deleted']}") # => Platform: chrome_login_data, deleted: 34 # 文本文件脱敏 from hygeia.text_sanitizer import sanitize_json, sanitize_log_file, sanitize_csv result = sanitize_json(Path("config.json")) # => {'action': 'sanitize_json', 'fields_redacted': 3, 'path': 'config.json'} # Pattern registry — 配置激活的 patterns from hygeia.patterns import load_patterns, list_available registry = load_patterns(only=["identity", "financial"]) # category filter registry = load_patterns(skip=["crypto"]) # exclude a category print(list_available()) # => {'identity': ['ssn', 'uk_nin', 'pan_card', ...], 'financial': ['credit_card', 'iban', ...], ...} # Forensic artifact 清理 from hygeia.filesystem_sanitizer import sanitize_filesystem actions = sanitize_filesystem(Path("/path/to/dump"), normalize_timestamps=True) # => [{'action': 'delete', 'path': 'LocalStorage/leveldb/', 'reason': 'leveldb_store'}, ...] # 脱敏后验证(fail-closed:通过要求零发现 # 且零未完成检查 — 见 result.incomplete / result.scope) from hygeia.verifier import verify_sanitization result = verify_sanitization(Path("/path/to/clean")) assert result.passed, f"{result.total_findings} findings, {len(result.incomplete)} incomplete checks" # => VerificationResult(passed=True, total_findings=0, incomplete=[], scope=None) # Compliance 驱动的脱敏 from hygeia.compliance import get_compliance_profile profile = get_compliance_profile("hipaa") sanitize_database_generic(Path("patient.db"), extra_columns=profile.extra_sensitive_columns, extra_tables=profile.extra_pii_tables) # => {'rows_redacted': 2341, 'pii_types_found': ['sensitive_column:mrn', 'npi', 'email']} ``` ## 可选依赖 ### exiftool(图像元数据剥离) HYGEIA 使用 [exiftool](https://exiftool.org/) 从图像中剥离 EXIF 元数据(GPS 坐标、设备制造商/型号、时间戳以及所有其他嵌入的标签)。如果没有该工具,步骤 [5/7] 将被静默跳过,图像元数据**不会**被移除。 如果启动时缺少 exiftool,HYGEIA 将打印: ``` WARNING: exiftool not installed. Image metadata will NOT be stripped. Install from https://exiftool.org/ to enable EXIF stripping. ``` 验证机制遵循同样的缺失逻辑:如果缺少 exiftool 且转储包含图像,步骤 [6/7] 会将这些图像报告为**不完整**的检查 — 既未剥离也未验证 — 而不是报告虚假的 PASSED。如果转储包含图像,请安装 exiftool,或者接受不完整的结果及其非零退出码。 **安装:** | 平台 | 命令 | |----------|---------| | macOS | `brew install exiftool` | | Debian/Ubuntu | `apt-get install libimage-exiftool-perl` | | Windows | 从 [exiftool.org](https://exiftool.org/) 下载并将 `exiftool.exe` 放置在 `C:\exiftool\` 或 `C:\Program Files\exiftool\` 中 | HYGEIA 会首先探测 `PATH`,然后在 Windows 上检查 `C:\exiftool\exiftool.exe` 和 `C:\Program Files\exiftool\exiftool.exe`,在 Unix 上检查 `/usr/bin/exiftool` 和 `/usr/local/bin/exiftool` — 因此独立的 Windows 安装无需将其添加到 `PATH` 即可工作。 要故意跳过 EXIF 剥离(例如在没有 exiftool 的环境中),请传入 `--skip-exif`。 ## 架构 ``` hygeia/ ├── cli.py 7-stage pipeline orchestrator + CLI argument handling ├── scanner.py File classification engine (DELETE/PRESERVE/SELECTIVE_DB/PLIST/EXIF) ├── patterns.py Central pattern registry — loads pii_patterns.json, compiles regexes, filters by --only/--skip ├── sqlite_sanitizer.py WAL-aware database sanitization — checkpoint → secure_delete → scan → VACUUM; safe identifier quoting, BLOB scanning, FTS3/4/5 fail-closed cleanup, secure-overwrite delete ├── platform_handlers.py 21 tested schema-aware handlers (Chrome, Firefox, iOS, Android, Windows, macOS) with table-signature auto-detection ├── text_sanitizer.py JSON, log, CSV/TSV sanitization + shell history deletion; context-pattern redaction (DOB, passwords, AWS keys, ...), fail-closed oversize handling ├── filesystem_sanitizer.py Forensic artifact removal — LevelDB, caches, swap, indexes; symlink-safe timestamp normalization ├── forensic_cleaner.py Anti-forensic hardening — slack space, ADS, extended attributes; symlink containment, concurrent-worker-safe cleanup ├── plist_sanitizer.py Binary plist credential redaction (recursive key-walk, incl. float/GPS values and location-hint integers) ├── exif_stripper.py Image metadata removal via exiftool (9 formats) ├── pdf_stripper.py PDF metadata stripping (author, creator, producer, keywords, XMP packets); symlink-safe in-place rewrite ├── office_stripper.py Office document metadata removal (docx/xlsx/pptx XML properties, tracked-changes/comment authors); DTD/entity-expansion guard ├── compliance.py HIPAA/GDPR/CCPA compliance profiles + evidence-based coverage reporting with a `limitations` field ├── verifier.py Post-sanitization PII verification (regex + freelist + EXIF) — read-only, fail-closed (`incomplete`/`scope`), exits 2 when it can't certify clean ├── manifest.py JSON audit trail generation ├── utils.py Shared helpers — SQL identifier quoting, symlink containment (`resolve_within`, `is_safe_regular_file`, `safe_utime`) └── rules/ ├── pii_patterns.json Single source of truth — 59 regex patterns + 9 context-gated patterns across 7 categories ├── delete_patterns.json 30 directory + 38 database + 10 extension patterns ├── preserve_patterns.json 18 directory + 5 file + 4 extension rules ├── selective_db_rules.json Column-level SQL for knowledgeC, Photos.sqlite, TCC.db └── plist_patterns.json 28 sensitive key patterns + path-based rules ``` 零外部 pip 依赖。仅使用标准库。可选的系统级 exiftool 用于处理图像元数据。 ## 限制 记录 HYGEIA 做不到的事情与记录它的功能同样重要: | 限制 | 详情 | |-----------|--------| | **加密数据库** | HYGEIA 无法读取或净化加密的 SQLite 数据库(例如 Signal 的 sqlcipher,经过 FileVault 加密的卷)。如果数据库需要密钥才能打开,它会在净化过程中被跳过并给出警告 — 并且由于验证机制是失败即关闭,同一个无法读取的数据库会被报告为**不完整**的检查,因此包含该数据库的转储会以退出码 2 而不是 0 退出。 | | **非 SQLite 数据库** | ESE 数据库(Windows WebCache,SRUM)会被识别并标记,但不会在内部进行解析。LevelDB 存储将被完全删除,而不是进行有选择的净化。 | | **二进制应用数据** | 专有的二进制格式(例如 Chrome 的 SNSS 会话文件,Firefox 的 sessionstore.jsonlz4 内部构件)将被删除,而不是进行精准修改。 | | **网络捕获** | 不解析 PCAP/PCAPNG 文件。如果你的转储包含数据包捕获,请单独移除它们。 | | **磁盘级工件** | HYGEIA 在文件系统级别运行。它无法擦除未分配的磁盘扇区、MFT 条目或文件系统下方的日志数据。为此,请在 HYGEIA 清理完逻辑文件后使用磁盘级工具。 | | **隐写术** | 不检测或移除图像值内嵌入的数据。EXIF/XMP 元数据会被剥离;像素内容保持不变。 | | **内存转储** | 原始 RAM 转储(.raw、.vmem、休眠文件)将被删除,但不会解析以提取 PII。 | | **语言检测** | PII 模式主要为英语/拉丁语系。中日韩文姓名、阿拉伯语标识符和非拉丁语系的个人数据可能与 regex 模式不匹配。在结构化数据库中,列名和表名检测仍然可以捕获到这些内容。 | ### 验证器抑制项(已知的误报过滤器) 净化后的验证器会有意抑制某些模式匹配,这些匹配在结构上与 PII 相同,但在上下文中并不属于个人身份信息。此处记录这些情况是因为过于激进的过滤器可能会掩盖真实的发现: | 模式 | 抑制条件 | 原理 | |---------|----------------|-----------| | `swift_bic` | 8 个字符的全大写字符串,或 ≤2 个唯一字符,或位于 `.plist` 文件内 | Apple plist 二进制数据包含运营商 bundle 标识符(例如 `BUNDLEID`),它们匹配 SWIFT 格式但不是银行代码。 | | `url_credentials` | URL 包含 `apple.com` 或 `cdn-apple.com` | Apple CDN 下载 URL 使用 `user:token@host` 格式进行经过身份验证的固件下载 — 这不是用户凭证。 | | `us_routing` / `cusip` / `south_korean_rrn` | 所有数字的值 ≤2 个唯一值,或位于 `.plist` 内 | 二进制 plist 中的顺序/重复数字字符串(`012345678`、`111111111`)是填充字节,不是财务标识符。 | | `dea_number` | 位于 `.plist` 文件内 | 运营商 bundle 校验和恰好匹配 DEA 字母数字格式。 | | `bitcoin_address` | 匹配项纯粹为十六进制(仅包含 `[0-9a-f]`) | 十六进制的 UUID 和哈希摘要值(ChromaDB embedding ID,git SHA)以 `1` 开头并匹配 base58 长度要求,但它们不是加密货币地址。真正的 Bitcoin 使用 base58(混合大小写,排除 0/O/I/l)。 | | `password_kv` | 列是向量数据库的内容列(`string_value`、`c0`、`metadata`、`document`) | Embedding 数据库存储了在上下文中自然包含“password”一词的对话文本 — 这不是实际的凭证键值对。 | | `ssn` | 列是 CoreData 内部属性(`z_pk`、`z_ent`、`zvalue`、`ztimestamp` 等) — **不再仅仅因为位于 `.plist`/`.json`/`.db` 文件内而被抑制** | Apple CoreData schema 中的顺序整数和 epoch 时间戳仅在列名上恰好匹配 9 位数的 SSN 格式。JSON/plist/db 导出文件中纯粹未格式化的 SSN(`123456789`)是真实发现,不再被文件扩展名一概隐藏。 | | `ip_v4` | 地址位于 RFC-1918 私有范围内,Apple 的 17/8 块,或所有均为单个数字组成的八位组 | 私有/内部 IP 和版本字符串(例如 `2.3.5.8`)不具备用户识别属性。 | | `gps_coord` | 值 > 180 或恰好为 `0`;未写成 `0.x` 的前导零整数部分(版本字符串);仅在 `.plist` 中结尾恰好为 4 位小数或具有 ≥8 位小数的值;或者 `external_mod_tag` 列 | 布局度量、版本号和同步标签匹配浮点格式,但不是地理坐标。小于 1 度的坐标(例如 `-0.1278`、`5.6231`)**不再被抑制** — 赤道纬度和本初子午线经度是真实的 GPS 数据 — 并且 4 位小数/≥8 位小数的布局度量规则现在仅适用于 `.plist`(以前在 `.json` 导出中也会抑制真实的 GPS 值)。 | **如果你怀疑某个抑制项隐藏了数据集中的真实 PII**,请运行 `hygeia --skip-verify`,然后使用你自己的工具手动检查输出结果。这些抑制项的存在是为了减少常见数据类型产生的干扰 — 它们并非绝对保证。 HYGEIA 会报告它跳过了什么。检查审计清单(`deletion_manifest.json`)中是否有任何已分类但未处理的文件 — 这些可能需要人工审查。 ## 许可证 PolyForm Noncommercial 1.0.0 — 免费用于研究、教育和个人使用。商业使用需要单独的许可证。详见 [LICENSE](LICENSE)。 ## 作者 **Kevin Estrada** ([@Indegosblade](https://github.com/Indegosblade))
标签:Homebrew安装, 逆向工具