diff --git a/README.md b/README.md index a2b1715..efe011d 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,9 @@ voucher/ │ ├── invalidate_form.ui # 作废弹窗表单 │ └── api/ # 薄封装 dspy(零 import,委托 init.py 注册函数) ├── scripts/ -│ ├── load_path.py # RBAC 注册(logined 全路径逐个精确配) +│ ├── load_path.py # RBAC 注册(logined;CRUD 目录只注册 index.ui+get_* 只读, +│ │ # 生成的 add/update/delete 写端点不注册——裸 sor.C/U/D 绕过 +│ │ # 全部业务校验,未注册即 403,写操作只走 api/ 有校验端点) │ └── seed_welcome_voucher.py # WELCOME400 种子(幂等) ├── i18n/{zh,en,jp,ko}/msg.txt # key=value 格式(merge_i18n 消费) └── pyproject.toml # packages = ["voucher", "voucher.rules"] @@ -126,6 +128,7 @@ cd - dspy 薄封装返回 dict(框架自动序列化),**禁 json.dumps 双重序列化**(Pitfall 38)。 - datetime 字段回前端必须 str 化(`_jsonable_instance`),框架 json.dumps 无 default=str。 - 弹窗表单 submited 事件的 params 是 **Response 对象**,要 `await resp.json()` 后再 widgetBuild(form.js dispatch 原始 resp)。 +- **【安全铁律】CRUD 生成的 add/update/delete dspy 不注册权限**:它们是裸 sor.C/U/D,绕过发券引擎原子占额/流水审计只读/org 隔离/状态守卫。只注册 index.ui + get_* 只读;写操作只走 wwwroot/api/ 有校验端点。2026-09-12 实测抓洞:统一注册四件套时 update/delete_voucher_usage_log.dspy 登录态 200 可篡改审计流水(已修,commit 0fbd0ca)。 ## 仓库