Skip to content

v3.1.2

Choose a tag to compare

@pollybird pollybird released this 13 Oct 14:06
· 8 commits to main since this release

安全修复版本(GitCode issue #2 五项中危 M1-M5)

本版本针对 GitCode 仓库 issue #2 提出的五项中危安全问题进行集中修复,无数据库结构变更、无新增依赖,覆盖代码重启即可生效。

M1 表单输入保护(int → safe_int)

文章/栏目/碎片/搜索/分页/页面构建器等表单参数原本直接 int() 转换,非数字输入会抛 ValueError 被 Flask 兜底为 500,暴露异常栈并消耗服务器资源。

  • 新增 app/utils/helpers.py::safe_int(value, default=0):strip + try/except 回退默认值
  • 替换 article_service / column_service / fragment.py / article.py / views.py / builder/widgets/data.py 等全部 int() 调用点
  • page / limit / per_page / offset 等索引类参数追加 max(1, ...),拒负数越界

M2 上传子目录白名单(路径穿越收口)

save_upload_file(sub_dir=...) 与 /admin/upload 的 type 参数原仅做拼接,攻击者可传 ../ 越界写入任意目录(如覆盖 app/static/ckeditor5/ckeditor.js 实施存储型 XSS)。

  • 新增 app/utils/uploads.py::_safe_sub_dir(sub_dir):白名单 common/image/file/avatar/editor/article/theme/site/column/fragment + 段格式正则 ^[a-zA-Z0-9_-]{1,32}$
  • 任一 ../ / 绝对路径 / 非白名单首段 / 非法段格式 均回退到 common
  • 双层校验:save_upload_file 入口 + /admin/upload 入口,纵深防御

M3 CKEditorFuncNum 反射型 XSS

富文本上传回调端点拼 <script>window.parent.CKEDITOR.tools.callFunction({func_num}, ...)</script>,func_num 原样透传未校验,攻击者可构造 1, document.cookie, " 注入任意 JS。

  • 仅接受 ^\d{1,6}$ 的 CKEditorFuncNum,非法直接 400
  • file_url / err 经 html.escape(..., quote=True) 后再拼入字符串

M4 SVG 上传管控

SVG 默认在上传白名单内(upload_allowed_exts 含 svg),但 SVG 可内嵌 <script> / onload= / <foreignObject> 等执行 JS,构成存储型 XSS。

  • 新增设置项 upload_allow_svg,默认 off;后台「上传安全」勾选后开启
  • 开启后做内容嗅探:拒绝 <script> / onload= / onclick= / href="javascript:" / <foreignObject> / onerror= / onmouseover=
  • 512KB 大小上限,防 DoS
  • .svg 静态响应强制 Content-Type: image/svg+xml; charset=utf-8 + X-Content-Type-Options: nosniff + Content-Security-Policy: sandbox; default-src 'none'; style-src 'unsafe-inline'; img-src 'self' data:,兜底防护存量 SVG
  • LOGO 上传同步联动:upload_allow_svg=off 时 LOGO 不接受 SVG

M5 登录验证码一次性消费

原登录流程仅在密码比对成功后才 session.pop('captcha'),比对失败时验证码留存,攻击者可同码反复提交枚举密码。

  • 登录提交后无论密码比对结果先 session.pop('captcha', None),杜绝同码复用

升级须知

  • 无数据库结构变更、无新增依赖,覆盖代码重启即可生效
  • 曾使用 SVG 作为 LOGO / 文章配图的站点,需到后台「系统设置 → 上传安全」勾选「允许上传 SVG」
  • 详见项目根目录 UPGRADE.md 与 CHANGELOG.md

测试与门禁

  • 新增 tests/test_security_m.py 23 项场景测试(M1 safe_int、M2 子目录白名单、M3 CKEditorFuncNum、M4 SVG 上传管控、M5 验证码一次性消费)
  • 全量 346 项测试通过(v3.1.1 的 320 项 + 26 项新增)
  • scripts/check_release.py 版本一致性检查通过(CMS_VERSION / CHANGELOG / README / wiki.html 均为 3.1.2)
  • scripts/check_constants.py 常量门禁通过(无违规裸字面量)

致谢

感谢 GitCode 用户在 issue #2 中提出的安全建议。