背景(2026-09-28 测试人员实测反馈):
「答题时大题部分有参考答案。」初判怀疑前端未区分 / 评分系统未隔离,
实测两条均被证伪:
· 前端 Competition.vue 仅渲染 description / sub_prompts,无答案区块;
· 后端 buildSnapshot() / getForCandidate() 返回字段无 answer;
· 建表 DDL 023-024 的 big_questions 无答案列;
· 真实联调 question 字段 = [big_question_uid, description, score_per_sub,
snapshot_at, sub_prompts, title, total_score]。
⇒ 泄露 100% 来自**题库录入内容**:中职组启用题 id=38 的题干内嵌
「指令输入示例」(>OFFMSG,COM1*4A 等三条),而第 3 小问正是问这些指令。
为什么守点是录入入口:
抽题快照 question_snapshot **抽题即固化**(防纠纷设计)⇒ 事后改题库
**撤不回**已抽考生看到的版本;下发链路本身无泄漏点 ⇒ 只能在录入时拦。
改动:
· 新增 detectAnswerLeak():扫 title / description / sub_prompt_1..3
① 「参考答案 / 标准答案 / 评分标准 / 评分细则 / 答案要点」字样;
② 带**字面参数**的指令示例(>CMD,值*两位十六进制校验码)。
· validateQuestionPayload() 内调用 ⇒ create 与 update **同源**拦截;
命中返回 code=SUSPECT_ANSWER_LEAK,message 直接教会管理员怎么改。
· 兼容 > 与裸 > 两种存储形态。
边界(刻意为之,勿收紧):
格式定义(参数用方括号占位,如 >OFFMSG[,Port[,Message]]*CS)**不拦** ——
校验码限定「两位十六进制」天然排除占位符 *CS(S 非 hex)。
向考生提供指令**手册**是允许的;等同于答案的**成品**才不允许。
—— 与同日数据修复口径一致(只删示例、保留格式定义)。
实测(后端已重启加载新码,5/5 PASS):
① 合法格式定义题 → 放行(code=0,新增 1 行)
② 含指令示例 → 拒绝 HTTP200 code=400,**未落库**
③ 含「参考答案」字样 → 拒绝,未落库
④ PUT 更新路径 → 同样拒绝,且原内容未被改写
⑤ 清理复原:行数与 MAX(id) 回到基线
30 KiB
30 KiB