[开发]SoSite 完整修复总结

👑Lv.11 元老 🌞 骨干会员
2026-10-23 23:58:41

本文由 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 → $_POST
  • app/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 全量拉取 + PHP array_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\View
  • plugins/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 项:

#问题文件修复
S1DatabaseController import 无 POST 校验DatabaseController.php:19加 && $_SERVER['REQUEST_METHOD'] === 'POST'
S2saveCss </style> 逃逸ThemeController.php:53加 str_replace('</style>', '', $css)
S3Autoloader 插件命名空间路径穿越Autoloader.php:45路径拼接前过滤 ..
S45 处 $_GET 裸传视图5 个 Controller全部加 htmlspecialchars()
S5TemplateCompiler extract() 变量覆盖TemplateCompiler.php 5 处全部加 EXTR_SKIP
S6UserController 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移除死 importF11
plugins/daily_checkin/hook/nav_plugin_links.php移除死 importF11


三、工作量统计

指标数据
涉及文件总数25 个(含删除 1 个)
代码改动行数安全修复 ~80 行 + 逻辑修复 ~30 行 + 架构清理 ~30 行 + 防御增强 ~25 行
净删除行数View.php 309 行 + 冗余代码 ~30 行
修复类型安全 8 项 / 逻辑 5 项 / 架构清理 5 项 / 防御增强 5 项
三轮修复耗时约 4 小时

轻量级、高性能、零 MySQL 依赖的PHP社区系统。
| 瀏覽 5 次 | 回覆 0 次

全部回覆 (0)

暫無回覆

請 登入