# 手工添加漏洞失败:会话关联校验修复 日期:2026-10-10(Asia/Shanghai)。 ## 工作流检查 - 用户请求:手工添加漏洞保存失败,截图报 `FOREIGN KEY constraint failed`。 - 阶段/类型:P10 反馈迭代,现有功能缺陷修复。 - 所需及已有依据:添加表单、POST 请求结构、创建 handler、数据库外键和可空字段均已核对。 - 缺失/假设:没有线上请求体,无法确认截图实际填写的会话 ID;代码可确认不存在的会话 ID 会触发该错误。手工漏洞可独立创建的行为沿用数据库现有可空设计。 - 允许实施:是;无需新的架构或产品决策。 - 范围:会话字段可选、关联存在性校验、三种语言提示、前后端回归。 - 验收:省略/留空会话可保存;有效会话可关联并继承项目;非法关联返回明确的 400;无权限关联继续返回 403;独立漏洞仍归属创建人。 ## 维护检查 - handler 608 行、database 漏洞模块 548 行、页面脚本 2584 行。页面脚本承担表单、筛选、卡片、复测等多个职责,文件大小属于 blocked 级别的广泛扩展风险。 - 允许类型:narrow_fix。本次仅从现有前端必填表达式去掉会话字段,不扩展该大文件行为;新测试放在独立文件,无需先做整体重构。 - 数据库代码不变,保留外键及现有 NULL 写入行为。 - 验证:Go handler/database 包测试、Node 添加/复测测试、JSON 解析、git diff --check。 ## 原因与修复 数据库允许 `vulnerabilities.conversation_id` 为 NULL,删除会话时也保留漏洞。但前端和 POST 请求强制会话必填,并允许用户自由输入未经存在性校验的 ID。填入不存在的 ID 后 INSERT 触发外键错误,接口返回 500。 会话改为可选并给出填写提示;接口修剪关联 ID 的首尾空白,在保留权限校验后检查显式会话和项目是否存在。无效关联返回 400,数据库查询异常仍返回 500。已存在的会话继续由原数据库逻辑自动关联项目。原有创建人归属及授权逻辑保留。 ## 验证记录 - Node 添加与复测回归:13 项通过。 - `go test ./internal/handler ./internal/database`:两个包全部通过,新建漏洞回归覆盖 9 个场景。 - 三种语言 JSON 解析及 `git diff --check`:通过。 - 线上部署和真实浏览器保存尚未验证。