From a904f5ff1131a7ac8826c07a37878fdaeb797317 Mon Sep 17 00:00:00 2001 From: 12451 <12451@example.com> Date: Sun, 20 Sep 2026 03:24:34 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E4=BF=AE=E6=AD=A3=20AGENTS.md=20?= =?UTF-8?q?=E9=99=90=E6=B5=81=E6=8F=8F=E8=BF=B0=E7=9A=84=E4=BA=8B=E5=AE=9E?= =?UTF-8?q?=E9=94=99=E8=AF=AF=20+=20=E8=A1=A5=E5=85=A8=E9=99=90=E6=B5=81?= =?UTF-8?q?=20location/zone=20=E6=B8=85=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - scan_abstract_zone 只挂在 location /api/pms/cabinets/abstract/(前缀匹配不命中 scan/); /api/cabinets/scan/{id} 需登录、无 token 恒 401、不构成枚举信号,无需限流 (实测:scan 60 连发 = 401x60/429x0;abstract 同法 = 404x23/429x37) - Nginx配置节的限流清单补上 abstract location 与第 4 个 zone scan_abstract_zone - 新增经验:写"某 zone 覆盖某某路径"必须按 location 前缀语义核对并附实测 429 清单, 不要按 zone 名字推断(scan_abstract_zone 这名字极易误导) --- AGENTS.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 7b4e293..cc30312 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -698,8 +698,8 @@ python tools/db.py exec "UPDATE users SET ..." # 写入 > ⚠️ **下面是"骨架节选",不是线上全文** —— 线上配置还包含(2026-09 实测): > 安全响应头(`Strict-Transport-Security` / `X-Content-Type-Options` / `X-Frame-Options` / > `Referrer-Policy` / `Content-Security-Policy-Report-Only`)、 -> **限流 location**(`= /api/pms/auth/login`、`= /api/pms/auth/challenge`,配合 -> `/etc/nginx/nginx.conf` 里的 `limit_req_zone auth_login_zone / auth_challenge_zone / uploads_zone`)、 +> **限流 location**(`= /api/pms/auth/login`、`= /api/pms/auth/challenge`、`/api/pms/cabinets/abstract/`,配合 +> `/etc/nginx/nginx.conf` 里的 `limit_req_zone auth_login_zone / auth_challenge_zone / uploads_zone / scan_abstract_zone`)、 > `location /uploads/`(免认证同源直出 + 限流 + `expires 30d`)、生产侧 `location = /pms { return 301 /pms/; }`、 > 测试侧 `location /h5/`。 > **改动前先拉线上真实文件为准**: @@ -922,8 +922,12 @@ scp -r software/web/dist/* root@118.31.119.206:/data/pms/web/ # 正式环境 ``` ⛔ zone 名要唯一;`limit_req_status 429;` 只需在主配置写一次(已在)。 > 现有 zone(2026-09 实测 4 个):`auth_login_zone` 10r/m、`auth_challenge_zone` 20r/m、 - > `uploads_zone` 120r/m、**`scan_abstract_zone` 30r/m**(扫码查设备 `/api/cabinets/scan/{abstract_id}` - > 与 `/api/cabinets/abstract/{abstract_id}` 这类**免认证**入口,是枚举攻击面)。 + > `uploads_zone` 120r/m、**`scan_abstract_zone` 30r/m** —— 只挂在 + > `location /api/pms/cabinets/abstract/`(**免认证**的扫码查设备入口,无 token 可枚举 `10-%08d`, + > 是真实攻击面)。 + > ⚠️ **`/api/cabinets/scan/{abstract_id}` 不在这个 zone 里**(前缀 `abstract/` 匹配不到 `scan/`)—— + > 它**需登录**、无 token 恒 `401`(与 id 是否存在无关),**不构成枚举信号,故无需限流**。 + > 实测:`scan` 同 IP 60 连发 = `401`×60 / `429`×0;`abstract` 同法 = `404`×23 / `429`×37。 2. **对应的 `conf.d/*.conf` 里给那个 location 挂 `limit_req`**: ```nginx location = /api/pms/ { @@ -938,6 +942,11 @@ scp -r software/web/dist/* root@118.31.119.206:/data/pms/web/ # 正式环境 ⛔ 不要跳过 `-t` 直接 `restart` —— 配置错会让**整站**(含生产域)起不来。 4. 把线上改动同步回 `deploy/nginx/` 的对应文件(见第 10 条),并在报告里注明。 + > 💡 **经验(写限流文档时必守)**:写"某 zone 覆盖某某路径"时,**必须按 `location` 的前缀语义核对, + > 并附实测 `429` 的路径清单** —— 不要按 zone 的名字推断它管谁 + > (`scan_abstract_zone` 这名字本身就极易让人以为它管 `scan`,而它的 `location` 只有 + > `/api/pms/cabinets/abstract/`;`scan/` 落在无 `limit_req` 的通用 `location /api/pms/`)。 + **2.1 微信小程序上传** 小程序构建产物 `dist/build/mp-weixin/` 不上传到服务器,而是通过微信开发者工具上传: