jerzy99jerzy/gmach
GitHub: jerzy99jerzy/gmach
一款完全离线运行的本地浏览器 cookie 审计与隐私反情报工具,用于分析和可视化跟踪器能从 cookie 中推断出的用户信息。
Stars: 0 | Forks: 0
# GMACH
**本地 cookie 存储反情报工具。** 解析浏览器 cookie 数据库,重构广告技术生态系统能推断出的关于你的信息,并标记具体的威胁——所有操作完全离线,在你的机器上本地执行。
得名于 Stanisław Lem 的《在浴缸中发现的回忆》中的“建筑”:一个全面监控的环境,其中每一件人造物都可能是信息,而每一条信息都可能是密码。该工具以它所映射的对手命名。
```
python gmach.py # scan Chrome / Edge / Brave / Firefox profiles
# -> gmach_report.json + gmach_purge.json
open dashboard.html # drag & drop the report (or serve both via http.server)
```
还没有报告?仪表板自带合成数据预览模式。
## 展示内容
- **曝光画像** - 从 cookie 域名推断出的兴趣领域(明确标注为推断,而非事实)
- **活动节律** - 基于 `last_access` 时间戳的 7×24 热力图:列表中的每个 tracker 都能在服务器端重构出相同的行为模式
- **同步爆发 / 跟踪种子事件** - 在 10 秒窗口内创建的 tracker cookie 集群:一次页面访问引发了跟踪浪潮,指向播种站点
- **跨浏览器关联** - 出现在 ≥2 个浏览器中的 tracker,即浏览器隔离无法提供隔离的域名
- **趋势与差异** - 仅追加的运行历史 (`gmach_history.jsonl`),跨运行的小图表,高亮显示包含新 tracker 的新增/移除域名
- **发现引擎** - 按严重性排序,每项发现都标记有来源:`measured` / `heuristic` / `inference`
- **清理列表** - 可操作的 `gmach_purge.json`(过期及广告技术候选);该工具绝不会写入活跃的浏览器数据库
## 发现 (v1.4)
| id | severity | trigger |
|---|---|---|
| auth-no-secure | high | 不带 `Secure` 的 session/auth 命名 cookie |
| persistent-id-cookies | high | 熵 >3.5 bit/char,长度 ≥16,生命周期 >30d(仅限 Firefox) |
| tracking-seed-events | medium/high | 在 10s 内创建了 ≥3 个 tracker 域名 |
| samesite-none-insecure | medium | 不带 `Secure` 的 `SameSite=None` |
| lifetime-gt-400d | medium | 超出 Chrome 生命周期上限 |
| adtech-footprint | medium/high | 广告技术域名密度 |
| fingerprinting-adjacent | medium | 设备智能 / 反机器人域名 |
| new-tracker-domains | medium | 上次运行中缺失的 tracker 域名 |
| cross-browser-tracking | medium | 在 ≥2 个浏览器中出现相同的 tracker |
| stale-cookies | low | 未使用 >180d,但仍然有效 |
| identity-graph | info | 跨服务登录生态系统 |
| session-hijack-surface | high/medium | 可通过 XSS/网络窃取的 auth/session cookie |
| jwt-identity-exposure | medium | 携带已解码身份声明的 JWT |
| pii-in-cookies | high | 在 cookie 值中发现 email/phone/uuid/ip |
## 机密层 (v1.4)
默认情况下,该工具仅读取元数据。机密层会更深入地探究 cookie 实际携带的内容——同时确保原始机密不会出现在任何可共享的产物中:
- **JWT 解码** - *你自己的* token 的 header 和 payload(无签名验证):签发者、主体、email、scope、过期时间。展示服务存储了关于你的哪些信息以及它们信任谁。PII 已脱敏。
- **Token 分类器** - session / auth / jwt / oauth_bearer / csrf / opaque_id。
- **值内 PII 扫描** - email、phone、UUID、内嵌 IP。在报告中已脱敏。
- **窃取影响评分 (0-100)** - 针对 cookie:如果它泄露,攻击者将获得什么收益,根据缺失 HttpOnly(可被 XSS 窃取)、缺失 Secure(可被网络拦截)、宽松的 SameSite、生命周期进行加权。
- **Session 劫持面** - 按窃取影响排序的 auth/session cookie。
- **重新识别指数** - 关于你在 tracker 集合 + PII/JWT 存在的情况下有多容易被唯一识别的相对信号(推断)。
**隐私架构——深思熟虑的设计,也是核心所在:**
- 主文件 `gmach_report.json` 绝不包含原始值。机密数据是派生并经过脱敏处理的(前缀 + 长度,隐去声明)。
- Firefox 的值是明文,因此机密层默认运行(仅限脱敏输出)。
- `--decrypt`(主动启用)使用当前用户自己的 OS 凭证解密 Chromium 值——属于自我作用域限制,与浏览器执行的操作相同;App-Bound-Encrypted 存储不会返回密钥,将被跳过。
- `--reveal`(主动启用)是原始值离开内存的唯一途径:它们会进入一个单独的 `gmach_confidential.json` 文件,权限为 chmod 600,带有警告标记,并被 gitignore 忽略。把它当作密码文件对待:分析完毕,然后删除。一个包含活跃 session token 的文件是个累赘,而不是功能——该工具的设计初衷就是必须让你明确要求才能保留它。
## 设计决策(刻意为之)
- **Chromium 解密是主动启用,而非默认**(`--decrypt`)。默认分析在元数据上运行。启用时,它使用当前用户自己的 OS 密钥材料,并受到 OS 加密的自作用域限制。
- **原始值绝不会进入主报告或历史记录。** 它们只能通过 `--reveal` 离开内存,进入一个单独的、被 gitignore 忽略的 0600 权限文件。可共享的报告永远不包含值。
- **读取前快照复制** - 安全处理来自运行中浏览器的被锁定 SQLite 文件;以只读方式打开源存储,绝不进行修改。
- **每项主张皆有出处。** Tracker 分类和朴素的 eTLD+1 明确标注为启发式方法;正在使用的方法会标记在报告元数据和仪表板页脚中。
- **完全离线的仪表板。** 零 CDN,零外部字体,除可选的本地报告获取外零网络调用。可在气隙环境中工作。
## 可选依赖项
- `pip install publicsuffix2` - 从内置的朴素启发式方法升级 eTLD+1 分组(自动回退并带有标记)
- `python gmach.py --tracker-list services.json` - 用 Disconnect 格式的列表替换内置的 tracker 快照
## 方法论注意事项
- `last_access` 会被浏览器覆盖:节律热力图是最后触及时间的快照,而不是完整的访问历史。
- 差异比较的是两次运行之间的域名集。更改扫描范围(不同的 `--path`,添加的浏览器)反映的是范围变化,而不是行为变化——保持范围一致才能得出有意义的趋势。自然的用法模式:每周的定时任务。
- 第三方状态由域名分类来代理,而不是通过请求上下文测量。
- Chromium 没有基于熵的 ID 检测(由于上述设计选择,值是加密的);元数据分析仍然完整。
- 内置的 tracker 列表是经过精心挑选的快照,并非详尽无遗——因此提供了 Disconnect 钩子。
- 发现结果和仪表板 UI 目前为波兰语;i18n 已列入待办事项。
## 许可证
MIT
标签:Cookie审计, 代码示例, 数据分析, 本地工具, 网络安全, 逆向工具, 隐私保护