本文由 FlintHub 开发文档归档发布。原始文档日期见标题前缀,来源:7月5日复制的资料/本次修复总结.md。
SoSite 完整修复总结
修复日期:2026-07-03
修复范围:25 个文件,共 23 项修复
覆盖类型:安全漏洞 / 逻辑缺陷 / 代码冗余 / 架构清理 / 防御增强
一、分项修复详情
1.1 RememberMe Token 轮换(F1)— 安全修复
- 风险:自动登录成功后 remember_token 不刷新,Token 永久有效。Cookie 一旦泄露攻击者可永久登录。
- 文件:
app/Helpers/RememberMe.php - 修复:验证成功后生成
random_bytes(32)新 Token → SHA256 哈希存入 DB → 更新客户端 Cookie(同setRememberCookie逻辑)
1.2 renderBadge XSS 转义(F2)— 安全修复
- 风险:
$cfg['icon']和$cfg['title']直接拼 HTML,level_config表被注入恶意内容时产生存储型 XSS。 - 文件:
app/Helpers/Points.php - 修复:2 行,对两个字段加
\htmlspecialchars(..., ENT_QUOTES, 'UTF-8')
1.3 MaintenanceController GET→POST(F3)— 安全修复
- 风险:5 个维护操作(重建索引、清理缓存、清理附件等)使用
$_GET['action']+$_GET['csrf'],CSRF Token 暴露在 URL / Referer 中。 - 文件:
app/Controllers/Admin/MaintenanceController.php— 全部$_GET→$_POSTapp/Views/admin/maintenance.php— 5 个<a href="...">链接 →<form method="POST">表单
1.4 500 错误信息隐藏(F4)— 安全修复
- 风险:未捕获异常直接输出
$e->getMessage()+$e->getFile():$e->getLine(),泄露内部路径和表结构。 - 文件:
index.php - 修复:详细信息写入
error_log,页面仅显示通用提示"服务器内部错误"
1.5 搜索权限 SQL 层过滤(F5)— 安全/性能修复
- 风险:每次搜索拉 500 条结果后在 PHP 层
array_filter做版块权限过滤,大表内存溢出风险。 - 文件:
app/Helpers/Search.php—search()及两个私有方法新增$allowedCategoryIds参数,SQL 层加AND category_id IN (...)app/Controllers/SearchController.php— 消除perPage=500全量拉取 + PHParray_filter,改为传参到 SQL 层
1.6 邮件发送结果检查(F6)— 逻辑修复
- 风险:
Mailer::send()返回['success'=>true/false, ...]但结果不被检查,SMTP 配置错误时用户注册成功却永远收不到验证邮件,无任何提示。 - 文件:
app/Controllers/AuthController.php - 修复:检查返回值,失败时显示具体错误、写入
error_log
1.7 TagsController 分页(F7)— 逻辑修复
- 风险:
Tag::getThreads()已支持$page/$perPage参数,但show()不传参,标签下 1000+ 帖子一次查完。 - 文件:
app/Controllers/TagsController.php - 修复:读取
$_GET['page']、传参给getThreads()、计算totalPages传给视图
1.8 删除重复 hook('init_after')(F8)— 逻辑修复
- 风险:
init.php:32已调用一次,index.php:156又调用一次,监听此钩子的插件执行两次。 - 文件:
index.php - 修复:删除
index.php:156的Plugin::hook('init_after')
1.9 $filteredRawThreads 变量初始化(F9)— 代码异味清理
- 风险:
$allowedIds为空数组时$filteredRawThreads未定义。虽然?? []兜底不报错,但仍是代码异味。 - 文件:
app/Controllers/SearchController.php - 修复:if 分支外提前初始化
$filteredRawThreads = []
1.10 ensureEmailVerifyColumns() 去重(F10)— 冗余清理
- 风险:
register()方法开始时调用一次,发邮件前又调用一次。第二次调用时表已存在直接 return,纯冗余。 - 文件:
app/Controllers/AuthController.php - 修复:删除首次调用 L107,保留发邮件前的 L155+注释说明
1.11 统一模板引擎(F11)— 架构清理
- 风险:View.php 和 TemplateCompiler.php 双模板引擎并存,~250 行重复代码。
- 文件:
app/Core/Router.php—new View()→new TemplateCompiler()app/Core/View.php— 删除(-309 行)plugins/daily_checkin/hook/nav_main_links.php— 移除死use app\Core\Viewplugins/daily_checkin/hook/nav_plugin_links.php— 移除死use app\Core\View
1.12 getDbType() 注释澄清(F12)— 注释完善
- 背景:审查报告说"无调用点",但实际 9 个插件文件仍在使用。不能删除。
- 文件:
app/Core/Database.php - 修复:添加完整注释说明"保留给插件兼容,仅 MySQL"
1.13 query() SQLite 替换注释澄清(F13)— 注释完善
- 背景:
INSERT OR IGNORE替换仍在被plugins/qa/QaController.php使用。不能删除。 - 文件:
app/Core/Database.php - 修复:注释改为"为插件代码兼容"
1.14 空方法注释完善(F14)— 可维护性
- 文件:
app/Helpers/Search.php - 修复:
syncThreadFTS()/syncBlogFTS()注释补充三要素:为何空(MySQL 实时同步)、保留原因(6 个调用点 API 兼容)、未来扩展点
1.15 后台批量移动提取公共方法(F15)— 消除重复
- 风险:
Admin/ThreadController和Admin/BlogController的batch_move代码几乎完全一样(15行 vs 11行)。 - 文件:
app/Controllers/Admin/BaseController.php— 新增batchMoveIds()公共方法app/Controllers/Admin/ThreadController.php— 调用公共方法app/Controllers/Admin/BlogController.php— 调用公共方法
1.16 登录锁定迁移到数据库(F16)— 安全修复
- 风险:
login_attempts和login_lock_until存在$_SESSION中,攻击者更换 Session ID 即可绕过锁定限制无限尝试密码。 - 文件:
app/Controllers/AuthController.php - 修复:锁定状态写入
settings表(key=_login_lock_<username_md5>),按用户名锁定,更换 Session ID 无法绕过
🔍 末轮全项目扫描附加修复
在完成上述 16 项计划修复后,对全部 128+ PHP 文件进行安全遍历,补充修复 7 项:
| # | 问题 | 文件 | 修复 |
|---|---|---|---|
| S1 | DatabaseController import 无 POST 校验 | DatabaseController.php:19 | 加 && $_SERVER['REQUEST_METHOD'] === 'POST' |
| S2 | saveCss </style> 逃逸 | ThemeController.php:53 | 加 str_replace('</style>', '', $css) |
| S3 | Autoloader 插件命名空间路径穿越 | Autoloader.php:45 | 路径拼接前过滤 .. |
| S4 | 5 处 $_GET 裸传视图 | 5 个 Controller | 全部加 htmlspecialchars() |
| S5 | TemplateCompiler extract() 变量覆盖 | TemplateCompiler.php 5 处 | 全部加 EXTR_SKIP |
| S6 | UserController goto 语句 | UserController.php:84 | 重构为 if/else |
二、文件改动总表
| 文件 | 改动类型 | 对应修复 |
|---|---|---|
index.php | 安全修复 + 逻辑修复 | F4, F8 |
app/Helpers/RememberMe.php | 安全修复 | F1 |
app/Helpers/Points.php | 安全修复 | F2 |
app/Helpers/Search.php | 安全/性能 + 注释 | F5, F14 |
app/Controllers/AuthController.php | 安全修复 + 逻辑修复 + 冗余清理 | F6, F10, F16 |
app/Controllers/SearchController.php | 安全/性能 + 代码异味 | F5, F9 |
app/Controllers/TagsController.php | 逻辑修复 | F7 |
app/Controllers/Admin/MaintenanceController.php | 安全修复 | F3 |
app/Controllers/Admin/BaseController.php | 架构/消除重复 | F15 |
app/Controllers/Admin/ThreadController.php | 消除重复 | F15 |
app/Controllers/Admin/BlogController.php | 消除重复 | F15 |
app/Controllers/Admin/DatabaseController.php | 安全修复 | S1 |
app/Controllers/Admin/ThemeController.php | 安全修复 + 防御增强 | S2, S4 |
app/Controllers/Admin/CategoryController.php | 防御增强 | S4 |
app/Controllers/Admin/GroupController.php | 防御增强 | S4 |
app/Controllers/Admin/LevelController.php | 防御增强 | S4 |
app/Controllers/Admin/TrashedController.php | 防御增强 | S4 |
app/Controllers/Admin/UserController.php | 消除 goto 语句 | S6 |
app/Core/Router.php | 架构清理 | F11 |
app/Core/Database.php | 注释完善 | F12, F13 |
app/Core/Autoloader.php | 安全防御 | S3 |
app/Core/TemplateCompiler.php | 安全防御 | S5 |
~~app/Core/View.php~~ | 删除(-309行) | F11 |
app/Views/admin/maintenance.php | 安全修复 | F3 |
plugins/daily_checkin/hook/nav_main_links.php | 移除死 import | F11 |
plugins/daily_checkin/hook/nav_plugin_links.php | 移除死 import | F11 |
三、工作量统计
| 指标 | 数据 |
|---|---|
| 涉及文件总数 | 25 个(含删除 1 个) |
| 代码改动行数 | 安全修复 ~80 行 + 逻辑修复 ~30 行 + 架构清理 ~30 行 + 防御增强 ~25 行 |
| 净删除行数 | View.php 309 行 + 冗余代码 ~30 行 |
| 修复类型 | 安全 8 项 / 逻辑 5 项 / 架构清理 5 项 / 防御增强 5 项 |
| 三轮修复耗时 | 约 4 小时 |