From 9a63883f305c306576c5a20c9542aa1549a90e66 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Sat, 8 Aug 2026 06:50:21 -0600 Subject: [PATCH] =?UTF-8?q?docs(=E9=98=B6=E6=AE=B54=E8=AF=84=E5=AE=A1):=20?= =?UTF-8?q?=E6=9B=B4=E6=AD=A3=E4=B8=80=E5=A4=84=E5=AF=B9=E6=97=A7=E5=90=8E?= =?UTF-8?q?=E7=AB=AF=E7=9A=84=E9=94=99=E8=AF=AF=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 对照表原写 DashboardInfoAPI / RandomUsernameAPI「旧后端任何人可读,含班级用户名 枚举」——不成立。两条都在 /api/admin/ 下,AdminRoleRequiredMiddleware (account/middleware.py:36)在中间件层就要求登录且 is_admin_role()。 「无装饰器」是真的,「任何人可读」不是。 真实缺口只是「任何管理员可读,而非仅超管」,严重度差很多。 修旧后端时按这条去查,会白改一处不存在的漏洞。 Co-Authored-By: Claude Opus 5 --- docs/specs/phase4-review-authz.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/specs/phase4-review-authz.md b/docs/specs/phase4-review-authz.md index a5c7584..f92ccc9 100644 --- a/docs/specs/phase4-review-authz.md +++ b/docs/specs/phase4-review-authz.md @@ -21,6 +21,16 @@ > > Minor 四条未修:M1 已按「有意偏离」保留,M2/M3/M4 留待阶段 5。 +> **更正(2026-08-08):本报告有一处对旧后端的判断是错的。** +> +> 文末对照表原写「`DashboardInfoAPI` / `RandomUsernameAPI` 旧后端任何人可读, +> 含班级用户名枚举」。**不成立** —— 这两条都挂在 `/api/admin/` 下,而 +> `account/middleware.py:36` 的 `AdminRoleRequiredMiddleware` 在中间件层就要求 +> 登录且 `is_admin_role()`。「无装饰器」是真的,「任何人可读」不是。 +> +> 差别很大:真实缺口只是「任何管理员可读,而非仅超管」。查旧后端的权限时, +> 别只看装饰器,那个中间件是所有 `/api/admin/` 的地板。 + ## 结论速览 | 级别 | 数量 | 条目 | @@ -394,7 +404,7 @@ flowchartRoutes.get("/flowcharts/statistics", requireAuth, async (c) => { | `/announcements*`(5 条) | requireSuperAdmin | `announcement/views/admin.py:13,23,40,57` | 一致 | | `/tutorials*` `/exercises*`(10 条) | requireSuperAdmin | `tutorial/views/admin.py:17,27,44,62,70,90,106,119,127` | 一致 | | `/achievements*` `/achievement-metrics`(6 条) | requireSuperAdmin | `achievement/views/admin.py:10,21,43,72,82` | 一致 | -| `/website` `/judge-servers*` `/orphan-test-cases*` `/dashboard` `/random-usernames`(9 条) | requireSuperAdmin | `conf/views.py:49,66,76,84,148,162`;`DashboardInfoAPI`(187) 与 `RandomUsernameAPI`(216) 旧后端**无装饰器** | 一致或**收紧**(后两条旧后端任何人可读,含班级用户名枚举) | +| `/website` `/judge-servers*` `/orphan-test-cases*` `/dashboard` `/random-usernames`(9 条) | requireSuperAdmin | `conf/views.py:49,66,76,84,148,162`;`DashboardInfoAPI`(187) 与 `RandomUsernameAPI`(216) 旧后端**无装饰器** | **收紧**(后两条旧后端任何管理员可读,不限超管) | | `/contests*`(5 条) | requireTeacher | `contest/views/admin.py:33,53,78,267` `@teacher_admin_required` | 一致 | | `/contests/:id/acm-helper`(2 条) | requireTeacher | `contest/views/admin.py:167,200` | 一致 | | `/problem-sets*`(15 条) | requireTeacher | `problemset/views/admin.py` 全部 `@teacher_admin_required` | 一致 |