Files
syly2/docs/analysis/syly2源码接手分析_20261029.md
T

212 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# syly2 源码接手分析
分析日期:2026-10-29
分析对象:2026-10-29 收到的原始 `syly2` 交接包,以外层工程为主要分析对象。
后续进展:同日已在 UAT 安装编译环境并成功打包,编译结果及后续入库验证见 [验证记录](../VERIFICATION.md)。本报告中的“未构建”描述保留首轮静态分析时的验证边界。
**入库说明(2026-10-30):** 本文保留对原始交接包的静态分析结论。后续维护基线已完成编译兼容修正、凭据迁出和本地离线验证;这些调整及历史 UAT 结果以 [仓库说明](../../README.md) 和 [验证记录](../VERIFICATION.md) 为准,不能据此认定本文其余风险已修复或当前版本已完成业务验收。正文中的文件数量、工具环境、缺少 Git/运维资料等描述均指首轮分析时的交接状态。
源码链接指向仓库中的对应文件,括号内行号保留原始交接包的位置,可能与入库后文件不同。未入库的原始 Nginx/SQL 文件仅保留路径与行号作为历史证据索引。附带的 CSV 记录原始两套源码的差异,不是当前仓库与交接包的差异。
## 1. 接手判断
这是一套具有较完整业务模块的传统 Java Web 单体系统,覆盖酒店、景区、旅行社及其他旅游业态的填报、审核、统计和上级系统同步。源码具有继续维护的基础,但交接包尚不能证明“可从零构建、完整恢复、与线上版本一致、安全接管”。
当前最优先的工作是确认版本基线、取得数据库与附件的完整备份、在隔离环境复现运行,并处理已经发现的认证与权限缺口。业务上的重点应放在“企业填报—区市审核—统计导出—省级上报”的完整链路。
本轮完成本地文件清点、源码副本比较、构建与部署配置检查、数据库 DDL 分析,以及登录、密码重置、酒店填报、审核、上传、省级同步等关键路径抽查。没有修改原始源码,也没有连接业务数据库、请求线上接口或执行交接 SQL。以下安全问题属于静态源码发现;线上是否部署相同代码、是否另有网关限制,尚未验证。
## 2. 交接包内容与版本问题
| 项目 | 当前结果 | 接手含义 |
| --- | --- | --- |
| 整个交接目录 | 12,598 个文件,约 210 MB(十进制) | 包含重复源码、第三方前端资源和编译产物,不能按总文件量判断业务规模 |
| 外层主 Java 源码 | `src/main/java` 下 910 个 Java 文件 | 本次业务分析的主要对象 |
| 额外源码目录 | `src/main/com` 下 21 个 Java 文件 | Eclipse 将其列为源码目录,POM 未见对应额外源码配置;主源码中未找到对 `com.taiji` 的直接 import,实际用途待确认 |
| 页面与控制器 | 538 个 JSP;去除注释后检出 139 处 `@Controller` | 包含业务、平台和示例代码,不等同于 139 个独立业务模块 |
| 两套源码 | 外层 `src` 5,219 个文件;内层 `syly2/src` 5,132 个文件 | 两者存在实质差异,不能任选一套部署 |
| 副本差异 | 同路径内容不同 198 个;仅外层存在 179 个;仅内层存在 92 个 | 差异覆盖登录、权限、报表、接口和配置 |
| 编译产物 | 外层 `target` 中 944 个 class,字节码版本均为 Java 8 | 是历史构建证据,不能代替本次重新构建 |
| 配置一致性 | 源码与 `target/classes` 的 `dbconfig.properties` 内容不同 | 直接使用旧 `target` 可能连接不同环境 |
| 版本与运维资料 | 未找到 Git 元数据、项目级 README、CI、容器部署文件和完整运维手册 | 提交历史、发布基线、启动与回滚步骤需要补交 |
外层比内层增加了密码哈希、登录失败记录、XSS 过滤、省级酒店服务及部分业态模块,可作为后续核对的候选基线;这不证明它就是当前生产版本。应取得线上 WAR、配置和构建记录,核对哈希与实际代码后再确定唯一维护版本。
副本差异清单见:[syly2源码副本差异_20261029.csv](syly2源码副本差异_20261029.csv)。CSV 只记录路径、差异类型和 SHA-256,不包含文件正文或凭证。
## 3. 技术架构与运行依赖
| 层次 | 源码与配置证据 |
| --- | --- |
| 工程 | Maven,`com.zzc:syly:1.0`,WAR,输出名 `syly` |
| Java | POM 的 source/target 为 1.8;现有 class 也为 Java 8 |
| Web 后端 | Spring MVC 3.2.18.RELEASE,传统 Servlet/JSP;存在 JEECG/ZZC 平台代码 |
| 持久化 | Hibernate Core 4.2.3.Final;部分配套 Hibernate 组件仍为 4.1.0.Final;另有 JdbcTemplate、MiniDao |
| 数据库 | MySQL,Connector/J 5.1.27,Druid 0.2.9 |
| 页面 | JSP、自定义标签、jQuery/EasyUI、Bootstrap/Ace;多个 jQuery 版本并存 |
| 文档与文件 | POI 3.9、CKFinder、UEditor、OpenOffice/JODConverter;存在 FastDFS 工具与配置 |
| 接口 | HTTP/JSON 与 Axis 1.4 SOAP 客户端并存,包含省级酒店、国家酒店、景区及旅行社对接代码 |
| 调度 | Quartz/Spring 定时任务配置;另有传统 TimerManager 同步监听器 |
| 日志 | Log4j 1.2.17;Hibernate 配置开启 SQL 输出 |
| 登录态 | HttpSession 配合 JVM 内的 ClientManager;未见统一外部会话存储 |
主要请求链路:
```mermaid
flowchart LR
A[浏览器 JSP 页面 / 移动端] --> B[Nginx]
B --> C[Tomcat / syly WAR]
C --> D[Spring MVC 与权限拦截器]
D --> E[Controller / Service]
E --> F[Hibernate / JdbcTemplate / MiniDao]
F --> G[(MySQL)]
E --> H[省级及国家旅游接口]
E --> I[附件 / 报表 / 文件预览]
```
Servlet 映射包括 `*.do`、`*.action` 和 `/rest/*`,页面不是独立前端工程。功能修改往往同时涉及 Java、JSP、SQL、字典与权限数据。
配置显示拟采用 Nginx HTTPS → 5080 → 8080 的多层代理,应用路径为 `/syly`。实际服务器、Tomcat/MySQL 版本、端口监听、防火墙和证书状态需要现场核验。FastDFS、文件预览、OpenOffice、短信与邮件在代码或配置中存在,其当前生产使用范围也需要确认。
证据:[pom.xml](../../pom.xml)(交接版第 1 行)、[web.xml](../../src/main/webapp/WEB-INF/web.xml)(交接版第 99 行)、[会话管理](../../src/main/java/com/zzc/web/system/manager/ClientManager.java)(交接版第 19 行)。
## 4. 主要业务与数据关系
| 模块 | 主要能力 | 核心表或代码位置 |
| --- | --- | --- |
| 酒店 | 基础资料、日报、月报、季报、年报、节假日与预计接待、审核、统计导出、省级同步 | `web/htoal`;`t_hotelmanage`、`t_hotel_day`、`t_hotelmonthly`、`t_hotel_quarterly`、`t_hotel_annual` |
| 景区 | 基础资料、周/月/季/年报、门票、分级审核、统计、上级同步 | `web/scenicmanage`;`t_scenicspot_info`、`t_scenicspot_weekly/monthly/quarterly/annual` |
| 旅行社 | 基础资料、国内/入境/出境季报、年度财务、统计与同步 | `web/travel`;`t_travelagency_info`、`t_travelagency_quarterly1/2/3`、`t_travelagency_annual` |
| 其他旅游业态 | 高尔夫、游艇、空中飞行、机场、动车、免税店、婚庆、海鲜排档等填报 | `web/otherTravel` 及相应月报表 |
| 管理与辅助 | 用户、角色、组织、菜单、数据权限、日志、公告、问卷、调查、填报积分、同步日志 | `web/system`、`notice`、`survey`、`questionnaire`、`sms` |
| 移动端 | 登录、企业资料与酒店/景区/其他业态报表 | `com.zzc.app`;另附 APK 文件,未见独立移动端客户端源码工程 |
以酒店月报为例,代码中的主链路是:登录用户对应酒店 → 保存月报 → 计算年初累计与积分 → 区级/市级审核或退回 → 按条件推送省系统 → 根据省端结果更新上报状态。月报有 `districtStatus`、`status`、`provinceState` 等不同字段,不能用单个“已审核”描述全部流程。
需要特别保留和核对的业务约束:
1. 多处代码以登录用户 ID 查找酒店实体,账号与企业主键存在紧密关联。迁移时需保留用户、企业、组织及角色的关联数据。
2. 通用审核状态、景区多级审核状态和省级推送状态并不完全一致,应分别整理状态表,不能直接合并数字编码。
3. 存在名称接近的酒店月报表,以及同一表对应多个统计实体的情况;不能仅凭名称清理“重复表”。
4. 月报累计、历史月份修改、积分、金额单位和省端指标映射是回归重点。省级推送代码仍可见 2025 年新增指标,历史接口实现不能直接代表现行口径。
证据:[酒店月报保存](../../src/main/java/com/zzc/web/htoal/controller/HotelMonthlyController.java)(交接版第 163 行)、[酒店月报审核](../../src/main/java/com/zzc/web/htoal/controller/HotelMonthlyController.java)(交接版第 706 行)、[状态定义](../../src/main/java/com/zzc/web/sylyUtils/Status.java)(交接版第 14 行)、[省端指标映射](../../src/main/java/com/zzc/web/htoal/service/impl/HotelProvinceServiceImpl.java)(交接版第 347 行)。
## 5. 优先风险与具体证据
优先级含义:P0 为接管前应立即核对和封堵的高危入口;P1 为隔离复现和接管验收前解决;P2 为稳定维护阶段逐步治理。以下没有进行线上利用验证。
### P0:免登录密码重置缺少必需的身份验证
`spring-mvc.xml` 将 `savenewpwdforuser` 排除认证;方法使用请求中的用户 ID 选择账号,仅当 `encryptedOldPassword` 非空才校验旧密码,随后更新密码及用户状态。代码路径没有要求当前登录身份、管理员权限或一次性重置凭证。
这构成账号接管风险。应将个人改密、管理员重置、过期密码修改拆为明确授权流程;过期密码场景也必须绑定已验证身份。已有 BCrypt 和密码复杂度检查不能弥补身份验证缺口。
证据:[认证排除项](../../src/main/resources/spring-mvc.xml)(交接版第 99 行)、[密码重置实现](../../src/main/java/com/zzc/web/system/controller/core/UserController.java)(交接版第 258 行)。
### P0:数据库修复入口被免登录放行
`repair` 在认证排除名单中;RepairController 直接调用 `deleteAndRepair()`,后者包含删除用户、角色关系、菜单、组织、日志等数据并重建默认数据的代码。
实际能否完整执行取决于运行版本、映射、约束及事务回滚,不能据此声称线上已经发生清库。但该危险调用链不应作为公开 Web 功能保留,更不能用它初始化恢复环境中的真实数据。
证据:[排除配置](../../src/main/resources/spring-mvc.xml)(交接版第 100 行)、[修复入口](../../src/main/java/com/zzc/web/system/controller/core/RepairController.java)(交接版第 58 行)、[删除与重建逻辑](../../src/main/java/com/zzc/web/system/service/impl/RepairServiceImpl.java)(交接版第 56 行)。
### P1:移动端统一绕过认证,写入接口信任请求中的企业 ID
AuthInterceptor 对包含 `appservice` 的请求直接放行。抽查酒店日报写入方法:从请求读取 `userId`,查找酒店并保存报表,没有在该路径核验登录凭证或企业归属;查询日报也直接使用传入 ID。
应给移动端建立统一认证,并由服务端身份确定企业归属。还需覆盖其余移动端接口及 Web 端按记录 ID 的修改、审核、删除操作。
证据:[移动端放行](../../src/main/java/com/zzc/core/interceptors/AuthInterceptor.java)(交接版第 79 行)、[日报读写](../../src/main/java/com/zzc/app/hotel/APPHotelController.java)(交接版第 91 行)。
### P1:文件上传直接使用原文件名并写入 Web 目录
FilesUploadController 将上传文件原名拼接到应用 `upload/` 目录后直接写入,方法内未见扩展名允许列表、随机重命名或规范化路径边界校验。可能产生目录穿越、文件覆盖以及上传脚本被容器执行的风险;具体利用条件取决于认证与容器配置。
应将上传文件放到非执行目录,使用服务端生成的文件名,并明确允许类型、大小和访问权限。
证据:[上传实现](../../src/main/java/com/zzc/web/upload/FilesUploadController.java)(交接版第 35 行)。
### P1:明文凭证与加密密钥随源码交接
数据库、邮件、监控页面配置中存在凭证;RSA 私钥和数据加密密钥在 Java 源码中以字面量定义。报告不记录这些值。
应盘点其用途与实际有效性,迁出源码并安排轮换。历史字段加密密钥的调整必须配套数据迁移或兼容解密,不能简单替换常量;现有字段 getter/setter 会调用加解密工具。
证据:[数据库配置](../../src/main/resources/dbconfig.properties)(交接版第 6 行)、[RSA 工具](../../src/main/java/com/zzc/core/util/RsaUtils.java)(交接版第 17 行)、[字段加密工具](../../src/main/java/com/zzc/core/util/EncryptionUtil.java)(交接版第 17 行)、[实体字段处理](../../src/main/java/com/zzc/web/htoal/entity/Hotelmanage.java)(交接版第 351 行)。
### P1:交付的 Nginx 配置有代理链路矛盾与边界问题
443 站点保留原 Host 转发到本机 5080;5080 的代理站点只匹配 localhost/127.0.0.1,另有返回 403 的默认站点。按该文件独立分析,正式域名请求可能在第二层代理落入默认站点而被拒绝。需与线上完整生效配置核对。
同时,`listen 5080` 没有绑定回环地址,“只允许本地”的注释不能形成来源限制;配置反射任意 Origin 且允许凭证,仍开启 TLS 1.0/1.1,并设置 10000m 请求体及很长的代理超时。应统一代理链路,收紧监听、跨域、TLS 与容量限制。
证据:5080 监听与默认站点:`www.sylytj.com.conf`(原始交接包第 23 行,未入库)、HTTPS 转发配置:`www.sylytj.com.conf`(原始交接包第 82 行,未入库)。
### P1:省级上报的页面成功提示不能证明省端接收成功
单条和批量月报上报 Controller 调用服务后直接返回“推送成功”。服务只有在省端 `ISSUCCESS` 为 true 时更新状态,但未把逐条结果返回 Controller;网络失败返回空值或省端明确拒绝时,存在页面仍提示成功的路径。汇总上报另有布尔结果判断,不能把这一问题泛化到所有接口。
上报验收应核对省端响应、每条记录的本地状态与同步日志。建议返回逐条结果并支持可追踪重试。另外,月报 HTTPS 客户端使用 NoopHostnameVerifier 并信任自签证书,需要建立明确的证书信任配置。
证据:[批量与单条返回](../../src/main/java/com/zzc/web/htoal/controller/HotelMonthlyController.java)(交接版第 2056 行)、[省端结果处理](../../src/main/java/com/zzc/web/htoal/service/impl/HotelProvinceServiceImpl.java)(交接版第 378 行)、[TLS 与异常处理](../../src/main/java/com/zzc/web/htoal/service/impl/HotelProvinceServiceImpl.java)(交接版第 763 行)。
### P1/P2:旧组件与权限模型需要专项回归
Spring 3、Hibernate 4、Log4j 1、Axis 1、旧版文件上传及文档解析组件形成较大的维护和安全负担;Hibernate 组件版本还不完全一致。这里依据 POM 做版本盘点,尚未执行依赖树解析或漏洞数据库扫描,不将“版本旧”等同于“某个漏洞已能利用”。
AuthInterceptor 对不在菜单管理表中的 URL 默认允许已登录用户访问;按钮显示权限不能代替后端操作授权。需建立企业、区级、市级和管理员的接口权限矩阵,并补查记录归属、状态转换、CSRF 与拼接查询。
外层源码已有 BCrypt、登录失败锁定、密码过期检查、XSS 过滤和部分参数化查询,说明做过一定加固;仍需对加固后的完整业务链路回归。
证据:[菜单外 URL 的处理](../../src/main/java/com/zzc/core/interceptors/AuthInterceptor.java)(交接版第 187 行)、[登录检查](../../src/main/java/com/zzc/web/system/controller/core/LoginController.java)(交接版第 111 行)、[BCrypt](../../src/main/java/com/zzc/core/util/PasswordUtil.java)(交接版第 21 行)。
## 6. 数据库、恢复与构建可复现性
### 数据资料
`sanya_ch.sql` 有 129 个建表语句;`sanya_ch_struct.sql` 有 130 个,新增表为 `t_login_fail_record`。两份文件均未发现 INSERT 数据语句。新结构中的 130 张表均为 InnoDB,字符集以 utf8 为主,另有一张 utf8mb4 表。
因此这两份 SQL 可用于了解结构,无法恢复业务记录、用户、菜单、角色、字典和接口配置。结构中虽然有 `flyway_schema_history` 表,本交接包未找到相应版本化迁移脚本体系。
`alter_table.sql` 扩展敏感字段长度;`add_magic_prefix.sql` 给非空字段添加加密标记,它本身不执行加密。执行前必须确认数据库里的历史值究竟是明文、无前缀密文还是带前缀密文,避免使明文被误识别为密文。
还需取得数据库一致性备份、上传附件、相关文件服务的数据,以及恢复与回滚步骤。Hibernate 的自动建表配置在 XML 中被注释,不能依靠 properties 中的 `update` 自动补齐结构。
证据:结构脚本:`sanya_ch_struct.sql`(原始交接包第 1 行,未入库)、字段长度脚本:`alter_table.sql`(原始交接包第 1 行,未入库)、加密标记脚本:`add_magic_prefix.sql`(原始交接包第 1 行,未入库)、[Hibernate 配置](../../src/main/resources/spring-mvc-hibernate.xml)(交接版第 86 行)。
### 构建与测试
- 当前终端 `java -version` 返回 Java 25.0.3;`mvn` 命令不存在。本轮没有执行 Maven 构建,不能给出编译通过结论。
- POM 固定 Java 8,bootclasspath 使用 `rt.jar/jce.jar` 及 Windows 分号分隔符,存在跨平台构建障碍。应先在隔离环境固定 JDK 8 和兼容 Maven,整理可重复构建步骤。
- CKFinder/Oracle 附有本地依赖安装说明,但命令引用原维护人员的 Windows 绝对路径;POM 依赖与 WEB-INF/lib 手工 JAR 并存,应核对私有依赖坐标、来源及完整性。
- Surefire 设置 `skip=true` 和 `testFailureIgnore=true`。`src/test/java` 只有 4 个 Java 文件,检出 1 个 JUnit `@Test`,未检出断言调用,尚不构成可用的业务回归保障。
- 报表 SQL、统计与导出集中在很大的类中,如 HotelSQL 13,465 行、ExportController 5,370 行。宜先建立业务基准样本,再局部修改和升级。
### 调度与连续运行
`web.xml` 中 TimerManager 注册被注释,不能因类里存在同步定时器就认定线上自动同步有效。Spring/Quartz 另有任务配置,需要结合数据库任务表、服务器计划任务和运行日志核对实际触发来源。
会话保存在应用进程内;重启会影响登录,多实例部署也需要处理会话一致性和定时任务重复执行。上述事项在扩容或迁移前应先验证。
证据:[编译与测试配置](../../pom.xml)(交接版第 804 行)、[本地依赖说明](../../jar/导入命令.txt)(交接版第 3 行)、[监听器配置](../../src/main/webapp/WEB-INF/web.xml)(交接版第 93 行)、[Quartz 配置](../../src/main/resources/spring-mvc-timeTask.xml)(交接版第 15 行)。
## 7. 建议的接手顺序与验收成果
| 顺序 | 工作 | 可验证成果 |
| --- | --- | --- |
| 1 | 确认生产版本、基础设施、域名证书、接口和数据责任边界 | 线上 WAR/配置哈希、唯一源码基线、环境与服务清单 |
| 2 | 核对并封堵 P0,盘点凭证与对外接口 | 修复清单;未登录、普通企业及管理员权限验证记录 |
| 3 | 在隔离环境构建和恢复,隔离真实上报、短信、邮件及自动任务 | 可重复构建的 WAR、完整恢复记录、配置模板、启动与回滚步骤 |
| 4 | 回归核心业务 | 酒店/景区/旅行社填报、审核退回、导出、省级上报及移动端的通过记录 |
| 5 | 建立运维保障并逐步升级 | 备份恢复演练、日志与告警、证书到期管理、版本发布记录、组件治理计划 |
优先补交的资料是:生产部署包及版本说明、完整数据库与附件备份、实际 Nginx/Tomcat 配置和运行版本、上级接口文档与授权交接、各角色权限与报表口径、计划任务及监控备份配置、近期缺陷和发布记录。账号与密钥应通过专门的安全渠道交接。
第一轮业务验收至少覆盖:登录/改密/锁定,企业之间的数据隔离,日报/月报/季报/年报保存与重复提交,跨年及历史月份累计,区市审核与撤回,金额与人数单位,导出结果,以及省端拒绝、超时、重试后的真实记录状态。
本报告可作为接手盘点和修复排序依据;构建成功、备份恢复成功、线上风险可达性和省级真实联调仍需后续取得运行证据。