7.4 KiB
7.4 KiB
安全扫描报告(静态审计)
日期:2026-10-16
方法:方案 A — 静态代码检索 + 关键路径人工研判
范围:backend/app/、web-admin/src/、mobile-oa-h5/src/、mobile-h5/、miniprogram/(业务源码)
排除:venv/、node_modules/、web-admin/public/tinymce/、纯 Demo HTML
本次不改业务代码;下列「建议」供后续专项修复使用。
摘要
| 风险 | 数量 |
|---|---|
| 高 | 0 |
| 中 | 2 |
| 低 | 3 |
| 信息 | 4 |
结论概要:
- 未发现典型的「用户输入直接拼进 SQL 字符串」的经典 SQL 注入(业务 CRUD 大量使用 SQLAlchemy ORM / 绑定参数
text(...):param)。 - 存在工作流「SQL 审批人」动态执行路径:黑名单不完整;前后端字段名不一致(
sqlExprvssql)可能使该能力当前未真正生效,但代码路径本身具备风险。 - XSS:商品详情查看已走
sanitizeHtml;其余v-html/innerHTML多为固定资源或已escapeHtml,风险较低。 - 弱口令:文档与基线默认
admin/111111;请用配套脚本将库中明文等价111111的账号改为Zkxw@123。
问题清单
M-01 工作流 SQL 审批人:动态执行 SELECT,黑名单可绕过
- 风险:中
- 位置:
backend/app/services/workflow_engine.py(约 26–28、306–317 行)_resolve_approvers/_FORBIDDEN_SQL_KEYWORDS - 简述:当审批节点
strategy == "sql"时,引擎对流程定义中的 SQL 模板执行db.execute(text(sql_template), variables)。虽要求以SELECT开头并禁止INSERT/UPDATE/DELETE/DROP/ALTER/CREATE/TRUNCATE,但未限制UNION、多语句、INTO OUTFILE、LOAD_FILE、耗时函数等;流程变量以绑定参数传入相对安全,SQL 模板本身若被有流程设计权限的账号写入恶意语句,可造成越权读库或影响可用性。 - 建议:仅允许预置白名单查询或受控 DSL;禁止自由 SQL;若必须保留,使用只读库账号 + 强制单语句解析 + 禁止分号/UNION/文件操作关键字;严格限制可编辑流程定义的角色。
M-02 流程设计器与引擎 SQL 字段名不一致(sqlExpr vs sql)
- 风险:中(安全相关功能缺陷;修复不当会放大 M-01)
- 位置:
- 前端:
web-admin/src/views/system/workflow/designer/FlowDesigner.vue(约 202–209、889 行)config.sqlExpr - 后端:
backend/app/services/workflow_engine.py(约 307 行)config.get("sql", "")
- 前端:
- 简述:设计器保存的是
sqlExpr,引擎读取的是sql。当前可能导致 SQL 策略实际取不到语句而失败;若后续只改一端对齐字段而未加固 M-01,会意外开启动态 SQL 执行面。 - 建议:统一字段名并做端到端测试;同时落实 M-01 加固后再启用。
L-01 ThemeSvg:fetch(src) 后 v-html 渲染 SVG
- 风险:低
- 位置:
web-admin/src/components/core/theme/theme-svg/index.vue(约 5、61–74 行) - 简述:将
src拉取的文本直接v-html。当前调用方(如登录页)传入本地/静态 SVG 路径,利用面小;若将来src可被不可信来源控制,SVG 内嵌脚本可能构成 XSS。 - 建议:限制
src为同源静态资源白名单;或对 SVG 做消毒后再渲染。
L-02 ArtTextScroll:v-html="text" 未消毒
- 风险:低
- 位置:
web-admin/src/components/core/text-effect/art-text-scroll/index.vue(约 23、29 行) - 简述:
text属性直接v-html。业务侧若传入用户/运营可编辑的 HTML,存在 XSS;当前主要被节日滚动等内部组件使用。 - 建议:默认按纯文本渲染,或统一走
sanitizeHtml。
L-03 highlight 指令:依赖调用方提供的 HTML
- 风险:低
- 位置:
web-admin/src/directives/business/highlight.ts(注释示例约 21 行;处理约 56–69、190 行) - 简述:假定宿主已用
v-html注入代码内容后再做行号等处理。若业务把不可信内容直接v-html再挂指令,会有 XSS。 - 建议:文档标明仅用于可信演示内容;业务展示代码用转义或消毒。
I-01 默认弱口令文档与基线账号
- 风险:信息
- 位置:
AGENTS.md、backend/README.md、deploy/docker/README.md(admin/111111) - 简述:默认口令便于本地联调,若生产未轮换则属高危配置问题(由弱密码刷新脚本处理库内口令)。
- 建议:生产执行
backend/scripts/reset_weak_password_111111.py;后续更新文档默认口令说明。
I-02 登录允许明文开关
- 风险:信息
- 位置:
backend/app/core/config.py(约 169–170 行)LOGIN_ALLOW_PLAINTEXT_LOGIN(默认False) - 简述:生产若误开,登录凭据可能以明文进入请求体。
- 建议:生产配置审计确保为
false。
I-03 API 加密 fail-open
- 风险:信息
- 位置:
backend/app/core/config.py(约 183–184 行)API_ENCRYPT_FAIL_OPEN(默认True) - 简述:加密中间件失败时放行,偏可用性;在加密本应强制的环境可能削弱传输层保护预期。
- 建议:生产按安全要求评估是否关闭 fail-open。
I-04 商品详情富文本已消毒(正向记录)
- 风险:信息(良好实践)
- 位置:
web-admin/src/components/business/product-view-dialog/index.vue+web-admin/src/utils/sanitize-html.ts - 简述:查看弹窗
v-html使用DOMPurify(sanitizeHtml),降低存储型 XSS 风险。 - 建议:其他富文本展示对齐同一工具。
分类检索结论
SQL 注入
| 检查项 | 结果 |
|---|---|
f"...SELECT/INSERT..." / % / .format 拼 SQL |
未发现(backend/app) |
text() 使用 |
biz_no_generator / sample_reception_lab_code 等为固定 SQL + 命名绑定参数,未见用户输入拼进语句 |
| 工作流动态 SQL | 见 M-01 / M-02 |
ORM filter 主路径 |
普遍使用绑定,未见字符串拼 WHERE |
XSS
| 检查项 | 结果 |
|---|---|
web-admin v-html |
商品详情已消毒;ThemeSvg / ArtTextScroll / highlight 见 L-01~L-03 |
mobile-oa-h5 打印 PDF |
exportOaApprovalPdf.js 对展示字段使用 escapeHtml 后再 innerHTML,风险可控 |
mobile-h5 document.write |
入口加载脚本用,非用户内容注入点 |
miniprogram |
未发现 v-html / innerHTML / eval 业务用法 |
其他
| 检查项 | 结果 |
|---|---|
| 工作流 callback SSRF | validate_callback_url 禁止 http(s),仅本地注册路径 — 正向 |
| 密码存储 | bcrypt(app/core/security.py)— 正向 |
| 依赖 CVE / 渗透 / 基础设施 | 未做(超出本次范围) |
局限
- 静态审计不能替代动态渗透与鉴权矩阵测试(水平越权、IDOR 等需接口级用例)。
- 未扫描第三方依赖 CVE、容器/主机配置、MinIO/Redis 网络暴露。
- Demo / 文档 HTML 中的
innerHTML未计入生产风险。
配套交付
- 弱密码刷新脚本:
backend/scripts/reset_weak_password_111111.py - SQL 说明:
docs/sql/2026-10-16-reset-weak-password-111111.sql - 设计说明:
docs/superpowers/specs/2026-10-16-security-scan-and-weak-password-design.md