MickeyAlton33/formsentry
GitHub: MickeyAlton33/formsentry
一款零依赖的 Google Forms 安全与隐私配置审计工具,能够自动发现表单并检测响应摘要公开、敏感 PII 收集等隐私泄露风险。
Stars: 0 | Forks: 0
# FormSentry 🛡️
**针对 Google Forms 的安全与隐私评估。**
将 FormSentry 指向一个 Google Form **或任意网页**,它将会
自动发现 Google Forms,像渗透测试人员那样审计每个表单的*外部可观察*
安全态势——**全程不会提交任何**
回复——并将所有结果汇总为一份单一的风险摘要。
它能发现现实中真正导致数据泄露的配置错误,并
对每个表单收集的个人数据进行分类(支持**英语*和*
希伯来语**),特别标记了国民身份证、未成年人、健康和支付数据。
```
━━ FormSentry report ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Target : https://forms.gle/XXXXXXXX
Title : רישום לאימוני שחייה לילדים
Risk : HIGH
Findings (5):
[HIGH] Collects minors' / children's data
Question(s): “שם הילד/ה”; “גיל הילד/ה”
→ Confirm the linked responses Sheet is shared 'Restricted', set a
retention/deletion routine, and verify a lawful basis.
[INFO] Response summary is restricted
The /viewanalytics endpoint is not public. Good.
```
## 缘由
Google Forms 是许多小型组织中隐形的后门。表单
*看起来*无害,但是:
- "**查看摘要图表和文本回复**" 只是一个简单的开关,就能将
分享链接变成**所有人答案**的公开垃圾桶。
- **关联的回复 Sheet** 经常被设置为 *"知道链接的任何人"*。
- 表单会悄悄收集**儿童姓名 + 年龄**、**国民身份证**、**健康
数据**,甚至**支付详情**——且没有保留政策,也没有 DPA。
FormSentry 将审核员通常需要手动执行的检查转化为了一个命令。
## 检查内容
| 检查项 | 出现问题的严重程度 | 方式 |
|---|---|---|
| 公开回复摘要 (`/viewanalytics`) | **严重** | Endpoint 返回 `200`,而不是重定向到 `analyticsrestricted` |
| 公开测验分数 (`/viewscore`) | **高** | Endpoint 返回 `200` |
| 收集支付卡数据 | **严重** | 问题文本分类器 |
| 收集国民身份证 / 护照 | **高** | 分类器(包括 `תעודת זהות`, `ת"ז`, passport) |
| 收集健康 / 医疗数据 | **高** | 分类器(包括 `רפואי`, `אלרגיה`) |
| 收集未成年人 / 儿童数据 | **高** | 分类器(包括 `ילד`, `גיל`, child/age) |
| 接受文件上传 | **中** | 问题类型 = file upload(存入所有者的 Drive 中) |
| 收集电话 / 地址 / 出生日期 / 财务信息 | **中** | 分类器 |
| 登录限制 / 组织限制 | 提示 | 登录重定向检测 |
| 关联 Sheet 分享提醒 | 低 | 始终提示——这是第一大泄露途径,且无法从外部察觉 |
## 安装
无依赖项。要求 Python 3.8+。
```
git clone https://github.com/MickeyAlton33/formsentry.git
cd formsentry
python3 formsentry.py --help
```
可选择将其加入您的 PATH 中:
```
install -m 0755 formsentry.py /usr/local/bin/formsentry
```
## 用法
### 评估已知表单
```
# 单个 form(URL、forms.gle 短链接或原始 form id 均可)
python3 formsentry.py https://forms.gle/XXXXXXXX
# 同时扫描多个
python3 formsentry.py https://forms.gle/AAA https://docs.google.com/forms/d/e/ID/viewform
# 从文件读取(每行一个目标;允许使用 '#' 添加注释)
python3 formsentry.py -i targets.txt
```
### 发现与批量分析 🔎
没有表单链接?将 FormSentry 指向一个页面——Linktree、网站、
任何链接枢纽——它会为您找到表单,然后对它们进行评估。
```
# 扫描页面以查找 Google Forms 并评估找到的所有内容
python3 formsentry.py --discover https://linktr.ee/some.org
# 仅列出找到的 forms(不进行评估)
python3 formsentry.py --discover --list-only https://example.org
# 抓取整个网站,深度为一跳(同一主机),上限为 80 页
python3 formsentry.py --discover --depth 1 --max-pages 80 https://example.org
# 从文件中的多个种子页面进行发现
python3 formsentry.py --discover -i seeds.txt --md -o audit.md
```
当评估的表单不止一个时,将会打印出一份**批量分析摘要**:
最高风险、按严重程度划分的统计、在整个集合中出现的 PII 类别,
并将最严重的违规项排在最前面。
```
╔══ MASS ANALYSIS SUMMARY ════════════════════════════
Forms assessed : 4
Worst risk : HIGH
By risk : 2 high 2 medium
PII seen : email address×4, phone number×4, name×3, minors' data×2
Needs attention (medium+):
[HIGH] Children's swim registration
...
╚═════════════════════════════════════════════════════
```
### OSINT:通过关键字 / 组织查找表单 🕵️
甚至连一个起始页面都没有?通过关键字搜索表单。
```
# 搜索与某个 ORGANIZATION 相关的 forms(将 dorks 范围限制在其域内)
python3 formsentry.py --search "Country HaAliya" --site example.org
# 按 KEYWORD 搜索 forms(自由文本)
python3 formsentry.py --search "swimming registration tel aviv"
# 仅打印可直接运行的 dorks(始终有效,无需 scraping),适用于 Google/Bing/DDG
python3 formsentry.py --search "country club" --dorks-only
```
获取结果的方式:
1. 如果设置了 `FORMSENTRY_SERPAPI_KEY`,它会查询 **SerpAPI**(可靠)。
export FORMSENTRY_SERPAPI_KEY=your_key
python3 formsentry.py --search "membership" --site example.org
2. 否则,它会执行**无需 key 的尽力抓取**(DuckDuckGo Lite + Bing)。
搜索引擎经常会阻止抓取——当发生这种情况时,FormSentry
**会打印出搜索指令**,这样您就可以在浏览器中运行它们,并
使用 `--discover -i pages.txt` 将结果反馈回去。
无论它找到什么,都会直接被导入到评估 + 批量分析流水线中。
### 按需示例
```
python3 formsentry.py --examples # full command chains for every mode
```
### 输出与 CI
```
python3 formsentry.py https://forms.gle/XXXX --json # JSON
python3 formsentry.py --discover https://site --md -o out.md # Markdown file
# CI gate:如果存在任何状态为 'high' 或更糟的情况,则以非零状态退出
python3 formsentry.py -i targets.txt --fail-on high
```
### 输出格式
- **默认** — 彩色终端报告(当表单 >1 时包含摘要)
- `--json` — 结构化 JSON:`{ "reports": [...], "summary": {...}, "discovered": [...] }`
(当表单 >1 时包含 `summary`;使用 `--discover` 时包含 `discovered`)
- `--md` — 带有问题表格的 Markdown 报告(+ 摘要部分)
### 退出码
`0` 干净 / 低于阈值 · `1` 发现结果 ≥ `--fail-on` · `2` 未提供目标。
## 工作原理
0. *(使用 `--discover` 时)* 获取每个种子页面,提取每个 Google Form 链接
(`forms.gle`、`docs.google.com/forms/...`、旧版 `goo.gl/forms`)——包括
链接枢纽页面中 JSON 转义的链接——并且在使用 `--depth` 时,会跟随
同主机链接以查找更多内容。按 form id 去重。
1. 解析 `forms.gle` 短链接,并将任何输入标准化为已发布的
`/forms/d/e//` form id。
2. 对公开的 `viewform` 页面执行 `GET` 请求,并解析内嵌的
`FB_PUBLIC_LOAD_DATA_` blob,以枚举问题、类型和必填标志。
3. 向 `/viewanalytics` 和 `/viewscore` 发出非跟随式的 `GET` 请求,并读取
状态 / 重定向结果以确定暴露情况。
4. 通过双语 PII 分类器运行每个问题标题。
5. 对发现结果进行评分,并打印 / 导出报告。
它从不发送 POST 请求,从不进行身份验证,也从不触及响应数据。
## 局限性
- 它无法查看**关联的 Google Sheet 的共享设置**(不存在
外部信号)——因此会一直提醒您手动检查它。
- 分类是基于启发式的;请审查它打印出的问题列表。
- Google 可能会更改 `FB_PUBLIC_LOAD_DATA_` 的结构;解析机制是防御性的,
在无法解析时会降级为“无法解析”,而不是直接崩溃。
## 开发
```
python3 tests/test_classify.py # offline unit tests, no network
```
## 许可证
MIT © 2026 — 详见 [LICENSE](LICENSE)。
标签:Google Forms, Homebrew安装, PII识别, SaaS安全评估, 安全合规审计, 文档结构分析, 网络安全, 逆向工具, 防御加固, 隐私保护