⚡ Deep Security Audit · 三层分析法

代码安全审计报告

ms-reminder + sms-tool 双子系统全维度安全审查 · 含攻击链组合分析与 2025-2026 最新供应链 CVE 调研

审计目标 /Users/home/code/sms
审计日期 2026-07-24
报告版本 v1.0
审计模式 Deep
总体风险评级
🔴 高危 (High)
存在 2 项 Critical:远程未授权完全接管 + 大规模 PII 泄露,无需任何凭据,仅靠网络可达即可利用。
1

执行摘要

Audit Summary
安全发现总数
0
2 Critical · 2 High · 3 Med · 12 Info
供应链 CVE 评估
0
覆盖 2025-2026 最新 CVE
确认可利用 CVE
0
均经代码级核实
覆盖安全维度
10/10
D1-D10 全维度覆盖
19 安全发现
严重度分布
Critical2
High2
Medium3
Info12
最关键发现
C-01空凭证登录(认证绕过)

auth.username/password 均为空字符串且 enabled=true,登录用 == 明文比较空串,发送空用户名/密码即获管理员权限;结合 0.0.0.0:5000 暴露,构成远程未授权完全接管。

C-02大规模 PII 未授权泄露

空凭证登录后可拉取全部短信日志;sms_reminder.log 明文记录 213 处手机号+真实姓名+部门,仓库无 .gitignore。

H-03远程触发批量短信发送

经 C-01 登录后 POST /run 可远程触发批量短信,造成资费损失与骚扰。

修复优先级路线
P0 · 立即(24h内)
C-01 强密码+非空校验+锁定;C-02 清理泄露日志
P1 · 短期(1周内)
H-03、L-02、M-03/M-04
P2 · 中期(1月内)
M-06、L-01~L-04、供应链升级
P3 · 长期改进
I-01~I-05、引入 SAST + 依赖扫描 CI
2

项目概述

Project Overview
🐍 ms-reminder 2C · 2H · 3M · 7I
技术栈
Python 3 / Flask 2.3.3
关键依赖
dmPython 2.5.32、requests 2.31.0、apscheduler 3.10.4、sqlite3
规模
~1060 行 Python
业务
一表通任务短信提醒服务:定时扫描达梦 DB 待办任务,对接收人发送提醒短信;提供 Web 管理(登录/日志/配置/触发扫描/调度启停)
☕ sms-tool 5 Info
技术栈
Java 21 / Spring Boot 3.2.0
关键依赖
spring-boot-starter-web 3.2.0(Spring 6.1.1)、jackson 2.16.0、Lombok、MAS SDK(本地 jar)
规模
11 个 Java 文件
业务
移动云 MAS 短信发送工具:通过 MAS SDK 向指定手机号发送一表通报表通知短信;REST API /api/sms/send,日志 JSON 存储
架构与数据流 2.3
▸ ms-reminder · Python/Flask · 0.0.0.0:5000 ▸ sms-tool · Java/SpringBoot · 127.0.0.1:8080 外部攻击者 / 本地进程 0.0.0.0 暴露 localhost 无认证 HTTP 明文 HTTP 明文 Web 路由 · app.py 路由入口 login_required 空凭证可绕过 C-01 /api/logs · /logs 日志查看 C-02 /config/update 配置修改 /run · /reminder/* 触发扫描 / 调度 SQLite sms_log.db app_config.json cursor.txt reminder.py 调度 + 发送 达梦 DB · ZBYC_TASK 待办任务库 sms.py · sendMsg.py 短信发送 内网短信 API 10.*.*.210:8080 sms_reminder.log 明文 PII · 213 处 C-02 SmsController /api/sms/send · 无认证 H-01 SmsService buildContent 内容拼接 H-02 MAS SDK Client masmgc.sdk.sms 移动云 MAS 平台 112.35.4.197:15000 sms_logs.json 已脱敏 ✓ 图例 处理节点 数据库 文件 漏洞点 认证关卡 安全实践 数据流 明文传输 PII 泄露路径 红色角标 = 关联漏洞编号(C-01 / H-01 等) 菱形为认证关卡,红色节点为漏洞所在
🔍 点击图片放大查看
攻击面清单 2.4
端点子系统绑定认证用途
POST /loginms-reminder0.0.0.0:5000无登录(C-01 空凭证)
GET / /logs /configms-reminder0.0.0.0:5000login_required(可绕过)页面查看
GET /api/logs /api/statsms-reminder0.0.0.0:5000login_required(可绕过)日志/统计 JSON
POST /run /reminder/*ms-reminder0.0.0.0:5000login_required + CSRF(可绕过)触发短信/调度
POST /config/updatems-reminder0.0.0.0:5000login_required + CSRF(可绕过)修改配置
POST /api/sms/sendsms-tool127.0.0.1:8080无发送短信(H-01)
⚠
🟠 高危提示 · 端口暴露风险
ms-reminder 使用 5000 端口、sms-tool 使用 8080 端口,均为攻击扫描工具的常用扫描目标(Flask 开发默认端口 + Java Web 默认端口)。建议修改为非常用高位端口(如 5xxx 随机高位),大幅降低自动化扫描工具发现服务的概率。
3

漏洞详情

Source → Filter → Service → Sink 完整证据链
🔬
每个漏洞均提供 Source(外部输入)→ Filter(安全控制)→ Service(业务处理)→ Sink(危险操作) 完整证据链,附实际文件:行号。点击卡片标题可展开/折叠详情。
3.1 ms-reminder 漏洞详情 2 Critical 2 High 3 Medium 7 Info
🔴 Critical C-01 空凭证登录(认证绕过) ▶
CVSS9.8
维度D2 认证
CWECWE-1392 / CWE-287
向量
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
证据链
  1. 配置(Sink 侧凭据) config/app_config.json:15-19
    auth.enabled=true 但 username/password 均为空字符串。
  2. 配置加载 config.py:47,77
    AUTH_CONFIG = {"enabled": true, "username": "", "password": ""}
  3. Source(外部输入) app.py:60-61
    攻击者提交空或省略字段 → request.form.get('username','') 得到 ''。
  4. Filter(不充分) login.html:30,34
    required 仅为客户端浏览器校验,curl/Burp 直接构造 POST 即可绕过;服务端无非空校验、无失败次数限制。
  5. Service + Sink(比较与登录) app.py:62-64
    '' == '' and '' == '' → True,设置 session['logged_in']=True 并重定向。
▶ 复现
# 攻击者发送空用户名/空密码即可登录,获得管理员 session
curl -i -X POST -d 'username=&password=' -c cookies.txt http://<目标>:5000/login
# 预期:HTTP 302 重定向到 /,cookies.txt 含 session
利用条件
能访问 ms-reminder 的 5000 端口(app.py:306 host='0.0.0.0' 对外暴露)
影响
远程未授权获得系统完全控制权,可查看所有日志、修改配置、触发短信发送
🔴 Critical C-02 短信日志大规模 PII 未授权泄露 ▶
CVSS7.5→Critical*
维度D3 授权 / D8 配置
CWECWE-200 / CWE-306
* 依赖 C-01;单独 7.5,组合后 Critical
  1. Source:外部攻击者经 C-01 获登录态后访问 /api/logs、/logs、/。
  2. Filter(被绕过) app.py:286-290
    @login_required 已被 C-01 绕过,jsonify(sms_logs) 直接返回全部日志。
  3. Service(读取日志) app.py:79-93
    SELECT * FROM sms_logs 返回 phone/content/indiv_name/task_dept_name 等全部字段。
  4. Sink(敏感数据返回 + 日志文件泄露)
    日志文件 sms_reminder.log(2578 行)明文记录 213 处 11 位手机号 + 真实姓名 + 部门 + 任务内容;全仓库无 .gitignore。
# logs/sms_reminder.log 实测样本(手机号已脱敏)
243: ... Virtual SMS sent to <手机号>: [*世奇]你好![丹江口市**局(丹江口市**局)]...
244: ... SMS sent successfully for task RW4203... to <手机号>
246: ... Virtual SMS sent to <手机号>: [*坤鹏]你好![郧西县**局]...
利用条件
能访问 5000 端口(C-01 登录)或能读取仓库文件
影响
大规模个人信息泄露,违反《个人信息保护法》《数据安全法》
🟠 High H-03 远程触发批量短信发送滥用 ▶
CVSS7.5
维度D9 业务逻辑
CWECWE-306
  1. Source:外部攻击者经 C-01 登录后 POST /run(携带登录后获取的 CSRF token)。
  2. Filter(被绕过) app.py:245-247
    @login_required(C-01 绕过)+ @require_csrf(token 登录时已生成,登录后可读取)。
  3. Service + Sink app.py:254-265 → reminder.py:76-137
    调用 reminder.process_reminder(),扫描达梦 DB 待办任务并循环 send_sms() 发送短信。
影响
攻击者可远程反复触发批量短信发送,造成短信通道资源耗尽、资费损失,并对任务接收人形成骚扰
🟠 High L-02 无登录失败次数限制 ▶
维度D2 认证
CWECWE-307

app.py:57-67 login() 无失败计数、无锁定、无延时。当前因 C-01 已无需爆破,但 修复 C-01 后此问题将暴露为暴力破解入口。

🟡 Medium M-03 配置篡改(start_id 游标) ▶
维度D9 业务逻辑
CWECWE-284

app.py:210-243:/config/update 在登录(C-01 可绕过)+ CSRF 后,将用户提交的 start_id 直接写入 cursor.txt 与 app_config.json,无业务合法性校验。reminder.py:37-43 以 start_id 为阈值,task_id <= start_id 则跳过。

影响
篡改游标 → 历史任务重复发送(骚扰+资费)或跳过待发任务(业务中断)
🟡 Medium M-04 日志明文 PII 泄露(仓库内) ▶
维度D8 配置/数据保护
CWECWE-532 / CWE-522
  • sms.py:45 logger.info(f"Virtual SMS sent to {phone}: ...") — 明文手机号+内容
  • sms.py:97 logger.info(f"SMS sent successfully to {phone}: ...") — 明文手机号
  • reminder.py:70 等多处记录手机号;实测 sms_reminder.log 2578 行含 213 处手机号+姓名+部门
  • 全仓库无 .gitignore(根目录、ms-reminder/、sms-tool/ 均无)
✓
对比:sms-tool 的 SmsService.maskMobile() 对日志手机号脱敏,是正确实践,ms-reminder 应参照。
🟡 Medium M-06 Session Cookie 安全属性缺失 ▶
维度D2/D8
CWECWE-614 / CWE-1275

app.py:11-12:未配置 SESSION_COOKIE_SECURE、SESSION_COOKIE_SAMESITE(HttpOnly Flask 默认开启,但 Secure/SameSite 缺失)。

影响
服务绑定 0.0.0.0 且为 HTTP,Secure 无法生效;SameSite 缺失降低 CSRF 防护深度
Info 级 ms-reminder · 7 项
编号项证据说明
M-01明文密码存储与比较app_config.json:18 + app.py:62 ==内网单机可接受;建议 bcrypt 存储 + hmac.compare_digest
L-01硬编码真实手机号sendMsg.py:58 mobile="158..."测试代码硬编码,建议改环境变量
L-03page 参数未校验导致 500app.py:164 int(...)?page=abc 触发 500;加 try-except 与范围校验
L-04登录表单缺少 CSRF 保护app.py:57-67登录 CSRF,影响有限;建议 Flask-WTF
I-01SECRET_KEY 每次重启随机app.py:12 os.urandom(24)安全可接受;建议持久化到环境变量
I-02.DS_Store 提交(通用)根目录/sms-tool/ 各 1 个macOS 元数据泄露目录结构,加入 .gitignore
I-04start_scheduler.py 引用不存在函数:37,44,54 start_backtrack_scheduler功能 bug(非安全),脚本运行会失败
3.2 sms-tool 漏洞详情 5 Info · 无 Medium 及以上漏洞
编号项证据说明
M-02MAS 凭据默认值application.yml ${SMS_MAS_USER:YBTsjj}环境变量注入机制合规,仅默认值含真实凭据需清理
H-01无认证短信发送接口SmsController.java:21 /api/sms/send仅本地可达;端口暴露则风险回升;建议认证+频率限制
H-02短信内容伪造SmsService.java:85-87 buildContent仅本地可达;建议长度限制+敏感词过滤
I-03system-scope 本地 jar 供应链不透明pom.xml masmgc.sdk.sms 1.0.3-SNAPSHOT本地 jar 无 CVE 跟踪,向移动云官方核实并锁正式版
I-05CORS 配置略宽WebConfig.java:11-16origins 合规,allowedHeaders("*") 偏宽,建议收窄
4

攻击链分析

Attack Chain Analysis
🔴 Critical 攻击链 A · 远程未授权 PII 泄露 + 业务破坏
1
扫描发现 ms-reminder (0.0.0.0:5000)
外部攻击者网络可达
2
C-01 空凭证登录
POST /login username=&password= → 获得管理员 session
3
C-02 PII 泄露
GET /api/logs → 获取全部短信日志(手机号/姓名/部门/内容)
GET /logs → 页面浏览
4
M-03 配置篡改
POST /config/update → 修改 start_id 游标 → 重复发送历史短信 / 跳过任务
5
H-03 短信滥用
POST /run → 远程触发批量短信发送(骚扰+资费)
⚠ 综合风险 Critical:远程未授权完全接管 + 大规模 PII 泄露 + 业务破坏,无需任何凭据
🟠 High 攻击链 B · 本地短信轰炸+钓鱼
1
访问 sms-tool (127.0.0.1:8080)
本地恶意进程/用户
2
H-01 无认证发送
POST /api/sms/send 循环调用 → 短信轰炸
3
H-02 内容伪造
注入钓鱼内容 → 带真实签名【十堰市**局】的钓鱼短信
综合风险 High:本地多用户/多服务可轰炸任意号码 + 政府签名背书钓鱼
🟡 Medium 攻击链 C · 凭据泄露→横向移动
1
源码/制品泄露
M-02 application.yml 硬编码 MAS 凭据
2
M-04 仓库日志泄露 PII
明文手机号+姓名+部门
3
获取 MAS 凭据
直接调用移动云 MAS 平台 → 绕过 sms-tool 完全控制短信发送
综合风险 Medium:凭据泄露后绕过应用层直接操作 MAS 平台
5

供应链 CVE 分析

Supply Chain · D10 · 2025-2026 最新 CVE
⚠
最重要结论:Spring Boot 3.2.0 已于 2026 年初结束 OSS 支持(EOL),上游不再为 3.2.x 提供安全补丁,新披露 CVE 甚至不再针对 3.2 版本评估。强烈建议升级至 3.5.x(OSS 支持至 2026-06)或 4.0.x。
评估 CVE 总数
0
Java 12 · Python 7 · 间接 4
确认可利用
0
利用前提均不满足
版本受影响
多数
但实际利用条件不满足
最紧迫治理项
Spring Boot EOL
3.2.0 已停止安全补丁
5.1 Java 依赖(sms-tool)
编号CVE依赖(版本)严重度受影响实际可利用建议
S-01CVE-2024-22243/22259/22262Spring 6.1.1High 8.1是否 未用 UriComponentsBuilder升级
S-02CVE-2025-41249Spring 6.1.1High是否 未引入 Spring Security升级
S-03CVE-2025-41242Spring 6.1.1High是否 需 Jetty,实为 Tomcat升级
S-04CVE-2025-22235Spring Boot 3.2.0High 7.3是否 未用 Security+actuator升级
S-05CVE-2026-22733Spring Boot actuatorHigh是否 无 actuator 依赖N/A
S-06CVE-2026-22737/22735Spring 6.1.1Med/Low是否 未用脚本模板/SSE升级
S-07CVE-2026-22732/40976Spring Security/Boot 4.0Critical 9.1否不受影响-
S-08CVE-2026-54515jackson 2.16.0Med 5.3是否 DTO 未用 @JsonIgnoreProperties升级至 2.18.9+
S-09jackson SSRFjackson 2.16.0Med是否 无 InetSocketAddress 字段升级至 2.18.8+
S-10CVE-2023-35116/2025-52999jackson 2.16.0-否不受影响 2.16.0 为修复版-
S-11-Lombok-否无 CVE 编译时注解处理器-
S-12-masmgc.sdk.sms 1.0.3-SNAPSHOT-未知本地 jar,公开库无记录向移动云核实
jackson 2.16 分支已于 2025-04 EOL,后续无安全补丁,应升级至 2.18.x LTS。
5.2 Python 依赖(ms-reminder)
编号CVE依赖(版本)严重度受影响实际可利用建议
S-13CVE-2026-27205Flask 2.3.3Low 4.3是部分 需缓存代理,内网直连风险低设 Cache-Control 或升级
S-14CVE-2026-25645requests 2.31.0Med 4.4是否 未用 extract_zipped_paths升级 2.33.0+
S-15CVE-2024-35195requests 2.31.0Mod 5.0是否 未用 Session+verify=False升级 2.32.2+
S-16CVE-2024-47081requests 2.31.0Mod 5.3是否 无 netrc升级 2.32.4+
S-17CVE-2026-31072apscheduler 3.10.4Critical 9.8否不受影响 双重证据:序列化器 4.0 引入 + 代码从未 import移除无用依赖
S-18CVE-2023-30861/32681Flask/requests-否不受影响 已为修复版本-
S-19-dmPython 2.5.32-未知公开库无记录向达梦核实
5.3 间接依赖(未锁定版本)
ℹ
requirements.txt 仅锁 4 个顶层依赖,Werkzeug / urllib3 / certifi 等间接依赖完全未锁定,且项目无 lockfile。
编号CVE间接依赖严重度利用条件建议
S-20CVE-2024-49767 / 2023-46136Werkzeug(未锁定)High 7.5部分 若 Werkzeug<3.0.6 则 multipart DoS 可利用锁定 ≥3.0.6 + lockfile
S-21CVE-2024-34069WerkzeugHigh 7.5否 需 debug 模式,本项目 debug=False建议 ≥3.0.3
S-22CVE-2024-49766/2025-66221WerkzeugMed否 仅 Windows+Python<3.11-
S-23CVE-2026-44431/21441/2024-37891urllib3(未锁定)Med-High否 需 ProxyManager/流式/跨域重定向锁定版本
5.4 复核结论
✓
真实可利用的供应链漏洞:0 项确认(所有版本受影响的 CVE 经代码级核实,利用前提均不满足)
需重点关注的治理风险
  1. Spring Boot 3.2.0 已 EOL(S-04~S-07 同类)— 最紧迫,升级至 3.5.x/4.0.x
  2. Werkzeug 版本未锁定(S-20)— 唯一可能真实可利用的 DoS,确认并锁定 ≥3.0.6
  3. jackson 2.16 EOL(S-08/S-09)— 升级至 2.18.x LTS
  4. apscheduler 无用依赖(S-17)— 从 requirements.txt 移除
  5. 间接依赖无 lockfile — 引入 uv lock / pip-tools 锁定全量依赖树
6

无漏洞维度

Clean Dimensions · 经核实确认安全
✓ D1SQL 注入

db.py 所有查询使用 ? 参数化占位符;reminder.py:149 LIKE ? 参数化;sms.py:16-19 INSERT 参数化。

✓ D1SSTI / XSS

Flask render_template 默认自动转义;4 个模板均无 |safe 用法;日志内容经 Jinja2 转义渲染。

✓ D4反序列化

Jackson 反序列化类型固定(SmsSendRequest、SmsLog),无 enableDefaultTyping/多态;Python 侧无 pickle.loads 用户输入。

✓ D5路径遍历

/config/update 写入路径固定(cursor.txt/app_config.json),不接受用户控制路径;read_system_logs 读固定路径。

✓ D6SSRF

短信 API URL 与 MAS URL 均来自配置文件,/config/update 不修改 sms_api.url,用户无法控制请求目标 URL。

7

修复建议

Remediation Roadmap · P0-P3 优先级
P0 · 立即修复
24 小时内
阻止远程未授权接管
  • C-01 设置强用户名/密码(非空、高熵);app.py:62 增加非空校验;密码改 bcrypt 存储 + hmac.compare_digest;增加失败计数与锁定(L-02)
  • C-02 修复 C-01 后未授权访问自然收敛;立即清理 sms_reminder.log 已泄露 PII;按 M-04 改造脱敏;/api/logs 按最小权限返回
P1 · 短期修复
1 周内
收敛高危与中危
  • H-01/H-02 /api/sms/send 增加认证+频率限制+每日配额;reportName 加长度限制+敏感词过滤;确认 server.address=127.0.0.1
  • 🔴 端口变更 ms-reminder 的 5000 → 改为非常用高位端口(如 5xxx 随机值);sms-tool 的 8080 → 改为 server.port=1xxxx,降低被自动化扫描发现的概率
  • H-03 修复 C-01 后收敛;/run 增加操作审计日志与二次确认
  • M-02 移除 application.yml 真实凭据默认值
  • M-03 /config/update 对 start_id 增加格式/业务校验
  • M-04 日志手机号脱敏;新增 .gitignore
P2 · 中期修复
1 月内
加固与供应链升级
  • M-06 配置 SESSION_COOKIE_SECURE/SAMESITE=Lax(启用 HTTPS 后)
  • L-01 移除硬编码手机号,改环境变量
  • L-03 page 转换加 try-except+范围校验
  • L-04 login() POST 加 @require_csrf 或 Flask-WTF
  • 供应链 Spring Boot →3.5.x/4.0.x;requests→2.33.0+;jackson→2.18.9+ LTS;锁定 Werkzeug≥3.0.6;移除 apscheduler;引入 lockfile
P3 · 长期改进
持续
工程化与可持续
  • I-01 SECRET_KEY 持久化到环境变量
  • I-02 .gitignore 加入 .DS_Store
  • I-03 MAS SDK 替换正式版本,向移动云核实
  • I-04 修复 start_scheduler.py 引用不存在函数的 bug
  • I-05 CORS allowedHeaders 收窄为实际所需头
  • 引入 SAST(Semgrep/SpotBugs)+ 依赖扫描(pip-audit/mvn dependency-check)纳入 CI
8

覆盖矩阵自检

Coverage Matrix · D1-D10 全维度覆盖
D1
注入
✓ 覆盖
无发现
D2
认证
✓ 覆盖
C-01 等 5 项
D3
授权
✓ 覆盖
C-02/H-01/M-03
D4
反序列化
✓ 覆盖
无发现
D5
文件操作
✓ 覆盖
无发现
D6
SSRF
✓ 覆盖
无发现
D7
加密
✓ 覆盖
M-01/M-02
D8
配置
✓ 覆盖
M-04 等 6 项
D9
业务逻辑
✓ 覆盖
H-03/M-03 等
D10
供应链
✓ 覆盖
S-01~S-23
✓
终止条件:D1-D3 均已覆盖,满足进入后续阶段要求;10 维度全覆盖。
9

未覆盖范围与说明

Out of Scope & Caveats
  1. 运行时环境:未实际部署运行,未做动态渗透;所有结论基于静态代码分析 + 配置/日志文件取证。C-01 可利用性已通过代码逻辑严格论证,但未执行实际 HTTP 请求复现。
  2. 达梦数据库侧:未审查达梦 DB 的配置、权限、视图层安全(仅审查应用层 SQL,均为参数化)。
  3. MAS SDK 内部实现:masmgc.sdk.sms-1.0.3-SNAPSHOT.jar 为二进制 jar,未反编译审查其内部实现,仅评估接口调用层。
  4. 部署环境:未评估生产部署的网络拓扑、反向代理、WAF 等。ms-reminder 实际风险取决于 5000 端口暴露范围;sms-tool 取决于 8080 是否严格保持 localhost。
  5. dmPython / masmgc.sdk.sms:公开漏洞库无记录,需向厂商官方核实。
  6. CVE-2026-31072(apscheduler):NVD 与 GitHub Advisory 描述存在矛盾,本项目初步判断不受影响,建议人工二次核实。
附录 · 审计依据
方法:三层分析法(面/线/点)+ Source→Sink 污点追踪 + 攻击链组合分析
维度框架:D1-D10 十维安全模型 + 三轨模型(Sink-driven / Control-driven / Config-driven)
供应链数据源:NVD、Spring 官方安全公告、GitHub Advisory、Debian Security Tracker、FasterXML Jackson Releases
原则:所有漏洞均附代码路径证据链;供应链 CVE 均核实实际利用条件,版本受影响但利用条件不满足的已标注。