内容
# EDUSRC Reporter
作者 [Stanley_Null](https://github.com/StanleyNull)
教育漏洞报告平台([src.sjtu.edu.cn](https://src.sjtu.edu.cn/))提交辅助工具:
- 油猴脚本:在 `/add/`、`/edit/` 注入侧边栏,点一条报告就把表单填完(含 Select2 单位/厂商、Vditor)
- MCP:在 Cursor 里查学校/厂商 ID、生成可导入 JSON
- 对照表:从提交页 `<select>` 一次性拆出,**不是手工列举**
对照表快照日期:`2026-08-28`
学校/单位 **5234**,厂商 **839**,漏洞分类 **17**。
---
## 目录
```
edusrc-reporter/
├── userscript/edusrc-autofill.user.js # Tampermonkey 脚本
├── mcp/server.py # Cursor MCP
├── data/
│ ├── firms.json # 单位 id + 官方名
│ ├── companies.json # 厂商 id + 官方名
│ ├── firm_name_to_id.json # 单位名 → id
│ ├── company_name_to_id.json # 厂商名 → id
│ ├── categories.json / levels.json
│ └── reports.json # MCP 生成结果(git 忽略)
├── templates/ # 可选:批量模板
├── examples/report.example.json
└── scripts/
├── lookup.py # 命令行查 ID
└── refresh_maps.py # 用登录 Cookie 刷新对照表
```
---
## 1. 安装油猴脚本
1. 浏览器安装 [Tampermonkey](https://www.tampermonkey.net/)
2. 打开管理面板 → **添加新脚本**
3. 删掉编辑器里的默认内容,粘贴 `userscript/edusrc-autofill.user.js` 全文,保存
4. 登录 EDUSRC,打开 [提交页](https://src.sjtu.edu.cn/add/)
5. 右侧会出现蓝色小箭头,点开即侧边栏
脚本只在 `https://src.sjtu.edu.cn/add*` 和 `/edit/*` 生效。
---
## 2. 导入报告并一键填充
报告 JSON 可以是数组,也可以是单条对象。字段见下方「报告 JSON 格式」。
1. 侧边栏点 **导入**
2. 把 JSON 贴进文本框(MCP 的 `export_reports` 输出、或 `examples/report.example.json`)
3. 点 **导入 / 更新**(相同 `id` 会覆盖)
4. 切回 **全部**,点一条报告
会自动写入:
| 表单 | 来源 |
|------|------|
| 标题 | `title` |
| 分类 / 等级 | `category` / `level`,中文名或平台 id 都行 |
| 单位 | `firm_id`;为 `0` 时用 `firm_name` 在页面下拉框里匹配 |
| 厂商 | `company_id`;为 `0` 时用 `company_name` 匹配,没有则需手选 |
| 是否需要凭证 | `credentials`(`True` / `False`) |
| 网络类型 | `network`(`internet` / `intranet`,默认互联网) |
| 漏洞 URL | `url`(textarea) |
| 详情 | `content` → Vditor |
已点过的条目会变淡。点 **清除已提交标记** 可恢复。**导出当前** 会把本地列表写回文本框,方便备份。
单位、厂商下拉框在提交页里已经带了全量 option,脚本只 `val()` + 触发 Select2,**不会清空 option**。
---
## 3. 报告 JSON 格式
```json
{
"id": "custom-北京大学-未授权访问",
"vuln_type": "custom",
"title": "北京大学",
"category": 16,
"level": "high",
"firm_id": 5903,
"firm_name": "北京大学",
"company_id": 3,
"company_name": "其他厂商",
"credentials": "False",
"network": "internet",
"url": "https://example.edu.cn/path",
"content": "## 漏洞描述\n\nMarkdown"
}
```
| 字段 | 必填 | 说明 |
|------|------|------|
| `id` | 是 | 列表去重键,导入时相同 id 覆盖 |
| `title` | 是 | **必须是学校官方名**(MCP 会强制改成对照表名称) |
| `category` | 是 | 数字 id,或中文:`未授权访问`、`SQL注入漏洞` 等 |
| `level` | 建议 | `low` / `medium` / `high` / `grave`,或 `低危` `中危` `高危` `严重` |
| `firm_name` | 建议 | 必须和平台官方名一致才能自动匹配 |
| `firm_id` | 否 | `0` 则按名称匹配 |
| `company_name` / `company_id` | 否 | 未知厂商用 `其他厂商` / `3` |
| `url` / `content` | 建议 | URL 与 Markdown 详情 |
| `vuln_type` | 否 | 仅用于侧边栏分组,任意字符串 |
| `credentials` | 否 | 默认 `False` |
| `network` | 否 | 默认 `internet` |
分类 id:AI漏洞 19,CSRF 6,SQL注入 1,SSRF 7,XSS 5,代码执行 3,任意文件下载 15,任意文件读取 14,其他 13,命令执行 4,弱口令 9,敏感信息泄露 10,文件上传 2,未授权访问 16,点击劫持 8,疑似被黑/存在后门 18,逻辑缺陷 17。
---
## 4. 查学校 / 厂商 ID
对照表在 `data/`,离线即可查。
```bash
python3 scripts/lookup.py 清华大学
python3 scripts/lookup.py 师范 --limit 20
python3 scripts/lookup.py --company 金智
python3 scripts/lookup.py --company 仰格
```
输出两列:`id` 和官方名。名称必须和 EDUSRC 下拉框一致(例如「中国石油大学(北京)」带括号)。
在 Cursor 里也可调 MCP:`lookup_firm` / `lookup_company`。本地没有时,可把登录 Cookie 传给这两个工具走 `/ajax/firm/list/`、`/ajax/company/list/` 补查(新加入的单位)。
---
## 5. 接入 Cursor MCP
1. 安装依赖:
```bash
python3 -m pip install -r mcp/requirements.txt
```
2. 把下面片段加进 `~/.cursor/mcp.json`(路径改成你的克隆目录):
```json
{
"mcpServers": {
"edusrc": {
"command": "/opt/homebrew/bin/python3",
"args": ["/path/to/edusrc-reporter/mcp/server.py"]
}
}
}
```
3. 重启 Cursor MCP。可用工具:
| 工具 | 作用 |
|------|------|
| `lookup_firm` | 查单位 id |
| `lookup_company` | 查厂商 id |
| `generate_custom_report` | 写一条自定义报告,id 为 0 时自动匹配对照表 |
| `generate_report` | 按 `templates/*.json` 套模板 |
| `batch_generate` | 同一模板多所学校 |
| `export_reports` | 输出可粘贴进油猴的 JSON |
| `list_templates` | 看模板和分类对照 |
| `clear_reports` | 清空本地 `data/reports.json` |
生成结果写在 `data/reports.json`(已 gitignore)。把 `export_reports` 的返回值粘进油猴即可。
自定义模板:复制 `templates/example.json`,改 `name`、`url_tpl`、`content_tpl`。占位符 `{domain}`、`{firm_name}`。
批量示例:
```text
batch_generate(
template_name="example",
targets_json='[{"domain":"www.pku.edu.cn","firm_name":"北京大学"}]'
)
```
`firm_id` 可以不填,MCP 会按学校官方名查对照表。
MCP 生成时:标题强制为学校官方名;分类 / 单位 / 厂商走对照表。正文怎么写不限。
---
## 6. 刷新对照表
平台加了新学校或新厂商时,用登录态重新拉提交页即可,不必手抄。
浏览器登录后,从开发者工具复制 `Cookie` 整串(至少包含 `sessionid`),然后:
```bash
export EDUSRC_COOKIE='sessionid=...; csrftoken=...'
python3 scripts/refresh_maps.py
```
脚本只 GET `https://src.sjtu.edu.cn/add/`,解析 `name="firm"` / `company` / `category` / `level` 四个 `<select>`。
---
## 7. 常见问题
**单位没填上**
`firm_name` 和平台官方名不一致。先 `python3 scripts/lookup.py 关键词` 抄官方名,或把 `firm_id` 写成对照表里的数字。
**厂商没填上**
同样必须用官方名。不知道厂商就 `"company_id": 3`、`"company_name": "其他厂商"`。
**Vditor 是空的**
详情有延迟写入,等一秒;若仍空,再点一次该报告。
**导入提示缺字段**
至少要有 `id`、`title`、`category`。
**对照表过期**
跑第 6 节刷新。提交页本身也带全量 option,油猴按名称匹配不依赖仓库里的 JSON。