第 10 章
安全设计
密码以 scrypt(含随机盐)哈希存储,不可逆;
本页目录
10.1 身份与会话
- 密码以
scrypt(含随机盐)哈希存储,不可逆; - 会话使用 HttpOnly + SameSite=lax Cookie,服务端保存会话表
login_sessions; - 退出登录会服务端销毁该会话(复制旧 Cookie 亦无法继续使用);
- 单账号支持最多 10 个并发会话,互不顶号;
- 账号状态(
disabled)在每次管理面鉴权时同步校验,停用立即生效。
10.2 权限模型
| 层级 | 判定 | 作用范围 |
|---|---|---|
| 角色 | student < teacher < admin < superadmin |
页面与接口能力 |
| 学校域 | school_id 一致 |
数据可见范围(题库、账号、场次、报告) |
| 房间域 | 房间创建者 / 校管理员 / 超管 | 实时答题与整卷场控操作 |
| 归属校验 | 资源归属(如草稿判分文件、导入批次) | 防止越权读取他人资源 |
管理面通过统一中间件拦截 /admin/*、/qbank/*、/api/admin/*、/api/qbank/*、/api/users/*、/api/import/*、/api/update/*,未登录或权限不足直接返回 401/403。
10.3 防爆破与限流
- 账号维度:连续失败 5 次锁定 5 分钟;隔离"多账号爆破"与"定向锁号"两类攻击;
- IP 维度:300 秒窗口内失败 20 次触发
429; - 登录失败返回统一文案,不区分账号不存在/密码错误/已锁定/已停用,防止账号枚举;
- 学校入驻申请接口同样带 IP 限流。
10.4 上传与内容安全
| 措施 | 说明 |
|---|---|
| 类型白名单 | 图片仅允许 png/jpg/jpeg/gif/webp;上传目录静态下发也仅放行图片扩展名 |
| 尺寸上限 | 按接口前缀设置请求体上限(16MB–512MB),资源级上限见 9.3 |
| 压缩包防护 | 题库包解压限制成员数与总字节数,防止"压缩炸弹" |
| 富文本清洗 | 服务端对富文本做标签/属性白名单清洗,前端渲染统一转义 |
| 路径安全 | 上传文件按服务端生成的文件名落盘,不接受客户端路径 |
| 仓储隔离 | 表格题三件套与学生作答存放于 excelstore/,不在 uploads/ 之下,避免被匿名直连下载 |
| 接口鉴权 | 判分资源读取按"教师题库范围 / 学生参与场次"鉴权;草稿资源带归属校验 |
10.5 反向代理与来源 IP
- 仅在确实部署在反向代理之后时才采信
X-Forwarded-For/Proto(由[app] behind_proxy=1或环境变量BEHIND_PROXY=1开启); - 建议同时用
[app] proxy_trusted_hosts收敛为反代真实 IP;留空表示信任任意来源(兼容旧部署,但该头可被伪造); - 未开启反代信任时,来源 IP 一律取 TCP 对端地址,避免被伪造来源误导排查;
- 本机关闭服务接口改用一次性令牌校验(
X-Stop-Token),避免反代场景下伪造X-Forwarded-For: 127.0.0.1关闭服务。
10.6 升级链路安全
| 措施 | 说明 |
|---|---|
| 清单完整性 | 清单与更新包必须携带 MD5,缺 MD5 一律拒绝 |
| 传输安全 | 默认仅 https;证书异常硬失败,除非显式允许明文 http |
| 来源限制 | 支持 manifest_hosts host 白名单 |
| 替换安全 | 旧文件改名 .old 作为回退备份,替换失败自动回滚;升级前自动备份数据库 |
| 版本比对 | 段数补齐比较,避免"同版本不同写法"造成升级死循环 |
10.7 数据与隐私
- 日志对
password/token/cookie/code等键名自动打码; - 初始密码清单下载有 30 天时效,并按批次创建人限制跨校下载;
- 学生答案与成绩按学校/房间隔离,学生只能查看本人记录(教师可查看本房间);
- 数据库为学生自持文件,便于学校自行备份、迁移与销毁。