[审计]SoSite 插件系统审计报告

👑Lv.11 元老 🌞 骨干会员
2026-10-25 00:10:32

本文由 FlintHub 开发文档归档发布。原始文档日期见标题前缀,来源:暂存20260913/docs/plugins_审计报告.md。

SoSite 插件系统审计报告

审计日期:2026-07-16

审计范围:plugins/ 目录下全部 13 个插件


一、全局问题(跨插件共性问题)

1.1 BASE_PATH 未使用 —— 二级目录部署兼容性问题

以下插件在钩子文件中使用了硬编码 URL,未拼接 BASE_PATH,部署在二级目录时会 404:

插件文件问题代码
announcementshook/announcements_display.php:16<link rel="stylesheet" href="/plugins/announcements/assets/style.css">
post_favoritehook/layout_head_end.php:15-16<link href="/plugins/post_favorite/assets/style.css"> + <script src="/plugins/post_favorite/assets/script.js">
friend_linkshook/home_sidebar_bottom.php:62<a href="/links/apply">
invitehook/layout_head_end.php:20form action="/register" 未用 BASE_PATH
daily_checkinhook/nav_plugin_links.php:12<a href="/checkin">(其他插件已修复)

建议:统一改为 <?php echo BASE_PATH; ?>/xxx 或使用 $view->url()。

1.2 冗余的 require_once 引入控制器

多个插件的 hook/route_register.php 中手动 require_once 控制器文件,但系统的 PSR-4 自动加载器已支持 Plugin\ 命名空间,这些是冗余的:

插件文件
announcementshook/admin_route_register.php:12-13
content_reviewhook/route_register.php:12-15、hook/admin_route_register.php:12-15
daily_checkinhook/route_register.php:14
dev_docshook/route_register.php:12、hook/admin_route_register.php:12-13
friend_linkshook/admin_route_register.php:13-15
qahook/route_register.php:12
red_packethook/route_register.php:13
seohook/route_register.php:12-13

建议:删除冗余的 require_once,自动加载器已能处理。

1.3 钩子文件中内联 CSS/JS

以下钩子文件直接输出大段 CSS 和 JS,未分离到独立样式文件:

插件文件问题
announcementshook/announcements_display.php内联 CSS+JS 滚动公告
friend_linkshook/home_sidebar_bottom.php内联 CSS 约 27 行
invitehook/layout_head_end.php内联 CSS+JS 注入注册页

建议:将 CSS 移到 assets/style.css,JS 移到 assets/script.js,保持钩子文件干净。

1.4 无 uninstall() 方法或 uninstall() 不完整

插件问题
red_packetplugin.json 中无 activated 字段,但插件不依赖 Plugin.php 的激活/卸载流程
daily_checkinuninstall() 只删 daily_checkin 表,没清理 users.points 字段和 settings 表
content_reviewuninstall() 可能未清理 review_notifications 表

建议:统一 uninstall() 清理所有相关数据。


二、逐插件问题

2.1 站点公告 (announcements) ✅ 基本良好

问题:

  • announcements_display.php 内联 CSS/JS,未分离
  • 硬编码 CSS 资源路径(见 1.1)
  • 公告关闭按钮使用 onclick 内联事件,不便于维护

建议:将 CSS 移到 assets/style.css,JS 移到 assets/script.js,用事件委托替代内联 onclick。


2.2 内容审核 (content_review) ⚠️ 有改进空间

问题:

  • 钩子目录残留 .bak 文件:admin_sidebar_links.php.bak、auth_register_after.php.bak、controller_view_before.php.bak、nav_user_menu_items.php.bak——共 4 个备份文件未清理
  • init_after.php 使用 try/catch 检测表是否存在,未使用缓存文件,每个请求都尝试查表
  • 插件已禁用(activated: false),但 .bak 文件仍应清理

建议:

  • 删除 .bak 文件
  • 参考 daily_checkin 的缓存文件模式,减少重复查表

2.3 每日签到 (daily_checkin) ✅ 质量较好

问题:

  • controller_view_before.php 中 $data['checkin_today'] 直接赋值,但 $data 变量来自钩子系统的 extract($params),如果 $params 中没有 data 键,$data 可能未定义
  • CheckinController.php 中登录检查用了 header('Location: /login'); exit; 而非 $this->requireLogin()
  • 导航链接硬编码 /checkin(见 1.1)

建议:

  • 统一使用 $this->requireLogin()
  • 钩子中使用 $data 前先检查是否已定义或使用 $data = $data ?? []

2.4 开发文档 (dev_docs) ⚠️ 需要关注

问题:

  • Plugin.php 异常庞大:insertDefaultData() 方法 1009 行,包含大量硬编码的 HTML 文档内容。整个 Plugin.php 共 1083 行,90%+ 是文档数据
  • 命名空间大小写不一致:AdminController.php:162 调用 \Plugin\dev_docs\Plugin::activate() 但实际命名空间是 \Plugin\DevDocs\Plugin(首字母大写)—— 这会导致 404 错误
  • init_after.php 为空:钩子文件存在但无任何代码
  • AdminController.php 中 slugify() 方法使用 preg_replace('/[^\p{L}\p{N}\s-]/u', '', $text) 无法处理中文转拼音,中文会被直接过滤掉
  • 插件已禁用(activated: false)

建议:

  • 将文档数据从 Plugin.php 移到独立的数据文件(如 data/default_docs.php)
  • 修复命名空间大小写问题
  • init_after.php 中补充建表逻辑(目前为空,依赖激活时建表,但激活后表可能被意外删除)

2.5 编辑信息 (edit_info) ✅ 质量较好

问题:

  • hook/init_after.php 完全为空,只有注释 —— 如果表被意外删除,没有兜底重建机制
  • post_edit_after.php 和 thread_edit_after.php 中建表时硬编码了 ENGINE=InnoDB DEFAULT CHARSET=utf8mb4,不兼容 SQLite

建议:

  • init_after.php 中添加惰性建表逻辑(参考 daily_checkin 的缓存模式)
  • 建表 SQL 使用 Database 类的方法,不要硬编码引擎

2.6 友情链接 (friend_links) ✅ 质量较好

问题:

  • home_sidebar_bottom.php 使用 emoji 🔗 作为标题图标,建议统一为 FA 图标
  • home_sidebar_bottom.php 中 <a href="/links/apply"> 硬编码,未用 BASE_PATH(见 1.1)
  • 内联 CSS 约 27 行(见 1.3)

建议:CSS 分离到 assets/style.css,URL 使用 BASE_PATH。


2.7 图标生成器 (icon_generator) ✅ 新插件

问题:

  • 需修改核心文件 TemplateCompiler.php 添加 bookmark 映射(已记录在安装说明中)
  • 预设模板当前仅支持内置预设,用户自定义预设未保存到数据库(可后续扩展)

建议:可用,后续可增加用户预设保存功能。


2.8 邀请注册 (invite) ⚠️ 有改进空间

问题:

  • 钩子目录残留 .revert 文件:init_after.php.revert——备份文件未清理
  • layout_head_end.php 中 preg_match('#^/register#', $_SERVER['REQUEST_URI']) 未考虑 BASE_PATH,二级目录部署时匹配失败
  • InviteController.php 使用 $db->begin() 和 $db->commit() 进行事务——需要确认 Database 类是否支持事务
  • 插件已禁用(activated: false)

建议:

  • 删除 .revert 文件
  • 使用 parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) 对比路径,或用 strpos 匹配含 BASE_PATH 的路径

2.9 帖子收藏 (post_favorite) ✅ 质量较好

问题:

  • layout_head_end.php 硬编码资源路径(见 1.1)
  • Plugin::toggle() 方法中没检查帖子是否存在就插入收藏记录,可能收藏不存在的帖子
  • FavoriteController.php 中 check() 方法用 $_GET 接收 thread_id,但未做 CSRF 保护(GET 请求无法验证 CSRF 是合理的,但需要确保操作是幂等的)

建议:

  • 资源路径加 BASE_PATH
  • toggle() 中先验证 threads 表存在该帖子 ID

2.10 问答系统 (qa) ⚠️ 较大

问题:

  • QaController.php 560 行,未完整审阅,但已知:
  • 路由使用 require_once 引入控制器(冗余)
  • 插件已禁用(activated: false)
  • Plugin.php 和 AdminController.php 未审阅

建议:启用前需完整测试。


2.11 积分红包 (red_packet) ⚠️ 有改进空间

问题:

  • RedPacketController.php 487 行,建表逻辑在控制器中而非插件激活钩子中:ensureTables() 方法在每次请求时检测表是否存在,未使用缓存文件
  • plugin.json 中 没有注册 init_after 钩子,插件激活时 Plugin::activate() 不会被自动调用
  • 但 RedPacketController::ensureTables() 在每次请求时都会尝试建表,这是冗余的

建议:

  • 在 plugin.json 中添加 init_after 钩子,使用缓存文件检测表存在
  • 移除 ensureTables() 中的每次请求建表逻辑

2.12 SEO 优化 (seo) ✅ 质量较好

问题:

  • layout_head_end.php:132 中 echo htmlspecialchars($seoCustomHead, ENT_QUOTES, 'UTF-8') 导致自定义代码(如统计脚本)无法正常输出,因为 <> 被转义了
  • FrontController.php 不继承 Controller,但直接输出 XML——功能上没问题,但缺乏统一错误处理
  • sitemap.xml 输出缺少 lastmod 标签的有效日期格式校验

建议:

  • $seoCustomHead 应使用 Content::decode() 或直接输出(管理员已登录后台,可信任)
  • 或增加说明:自定义头代码中不能包含 <> 字符

2.13 用户主页 (user_profile) ✅ 质量较好

问题:

  • FrontController::show() 中 404 直接 echo '<h1>404...</h1>'; exit; 而非使用框架的错误页面
  • handleCsrf() 方法为 private,但被 follow() 和 unfollow() 调用——PHP 中可行,但设计上不太优雅
  • nav_plugin_links.php 只包含注释,无实际代码——既然不需要导航链接,可不在 plugin.json 中注册该钩子

建议:

  • 404 使用 $this->view('errors/404') 或 http_response_code(404) 加模板渲染
  • 不需要的钩子从 plugin.json 移除

三、安全隐患汇总

级别问题涉及插件说明
低自定义头代码被转义seo$seoCustomHead 经 htmlspecialchars 输出,统计代码无法使用
低404 直接退出user_profile未使用框架统一错误页
信息硬编码资源路径多个二级目录部署时资源加载失败
信息冗余 require_once多个不影响功能,但增加维护成本

未发现明显的高危安全漏洞(SQL 注入、XSS 等),各插件均使用了参数化查询和 htmlspecialchars 输出。


四、文件清理

以下文件应删除:

文件说明
plugins/content_review/hook/admin_sidebar_links.php.bak备份残留
plugins/content_review/hook/auth_register_after.php.bak备份残留
plugins/content_review/hook/controller_view_before.php.bak备份残留
plugins/content_review/hook/nav_user_menu_items.php.bak备份残留
plugins/invite/hook/init_after.php.revert备份残留
plugins/announcements/hook/init_after.php.revert备份残留


五、总结

插件质量评级主要问题
announcements✅ 良好内联 CSS/JS,BASE_PATH
content_review⚠️ 待改进残留 .bak 文件,无表缓存
daily_checkin✅ 良好小问题(登录检查方式)
dev_docs⚠️ 需关注Plugin.php 过于庞大,命名空间错误
edit_info✅ 良好init_after 为空,SQLite 兼容
friend_links✅ 良好内联 CSS,emoji 图标
icon_generator✅ 新需修改核心文件
invite⚠️ 待改进残留 .revert 文件,BASE_PATH
post_favorite✅ 良好BASE_PATH
qa⚠️ 未启用待完整审阅
red_packet⚠️ 待改进建表逻辑在控制器中
seo✅ 良好自定义头代码转义问题
user_profile✅ 良好404 处理方式

最快可修复的问题(按优先级):

  1. 删除 6 个残留备份文件
  2. 修复 dev_docs 的命名空间大小写 bug
  3. 修复 seo 的自定义头代码转义问题
  4. 给各插件资源路径加 BASE_PATH
轻量级、高性能、零 MySQL 依赖的PHP社区系统。
| 瀏覽 4 次 | 回覆 0 次

全部回覆 (0)

暫無回覆

請 登入