安全与可靠性: 修复配额并发、投票事务、密码授权与导出完整性
This commit is contained in:
@@ -7,6 +7,7 @@ package question
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -101,6 +102,29 @@ func AskStatusAPI(ctx context.Context) error {
|
||||
return ctx.ServerError()
|
||||
}
|
||||
|
||||
// SEC-06:与 ListAPI(route/question/page.go)对齐,补上 L4 和页面密码检查。
|
||||
// 否则持有正确问题 token 的请求者可以绕过页面访问边界,取得回答状态、
|
||||
// 创建时间和前 60 字摘要。
|
||||
// 两者都返回「用户不存在」以隐藏真实原因(不暴露处置状态与密码设置)。
|
||||
if level, _, err := db.Restrictions.ActiveLevel(ctx.Request().Context(), owner.ID); err == nil && level == db.RestrictionL4 {
|
||||
out := make([]askStatusResult, 0, len(req.Items))
|
||||
for _, it := range req.Items {
|
||||
out = append(out, askStatusResult{ID: it.ID})
|
||||
}
|
||||
return ctx.JSON(map[string]interface{}{"items": out})
|
||||
}
|
||||
if owner.PagePassword != "" && !(ctx.IsLogged && ctx.User.ID == owner.ID) {
|
||||
passKey := fmt.Sprintf("page_pass_%d", owner.ID)
|
||||
sessionVer, _ := ctx.Session.Get(passKey).(uint)
|
||||
if sessionVer != owner.PagePasswordVer {
|
||||
out := make([]askStatusResult, 0, len(req.Items))
|
||||
for _, it := range req.Items {
|
||||
out = append(out, askStatusResult{ID: it.ID})
|
||||
}
|
||||
return ctx.JSON(map[string]interface{}{"items": out})
|
||||
}
|
||||
}
|
||||
|
||||
// 收集合法 ID 并一次查回(IN 查询,避免逐条 N+1)。
|
||||
ids := make([]uint, 0, len(req.Items))
|
||||
for _, it := range req.Items {
|
||||
|
||||
Reference in New Issue
Block a user