本文由 FlintHub 开发文档归档发布。原始文档日期见标题前缀,来源:暂存20260913/docs/plugins_审计报告.md。
SoSite 插件系统审计报告
审计日期:2026-07-16
审计范围:
plugins/目录下全部 13 个插件
一、全局问题(跨插件共性问题)
1.1 BASE_PATH 未使用 —— 二级目录部署兼容性问题
以下插件在钩子文件中使用了硬编码 URL,未拼接 BASE_PATH,部署在二级目录时会 404:
| 插件 | 文件 | 问题代码 |
|---|---|---|
| announcements | hook/announcements_display.php:16 | <link rel="stylesheet" href="/plugins/announcements/assets/style.css"> |
| post_favorite | hook/layout_head_end.php:15-16 | <link href="/plugins/post_favorite/assets/style.css"> + <script src="/plugins/post_favorite/assets/script.js"> |
| friend_links | hook/home_sidebar_bottom.php:62 | <a href="/links/apply"> |
| invite | hook/layout_head_end.php:20 | form action="/register" 未用 BASE_PATH |
| daily_checkin | hook/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\ 命名空间,这些是冗余的:
| 插件 | 文件 |
|---|---|
| announcements | hook/admin_route_register.php:12-13 |
| content_review | hook/route_register.php:12-15、hook/admin_route_register.php:12-15 |
| daily_checkin | hook/route_register.php:14 |
| dev_docs | hook/route_register.php:12、hook/admin_route_register.php:12-13 |
| friend_links | hook/admin_route_register.php:13-15 |
| qa | hook/route_register.php:12 |
| red_packet | hook/route_register.php:13 |
| seo | hook/route_register.php:12-13 |
建议:删除冗余的 require_once,自动加载器已能处理。
1.3 钩子文件中内联 CSS/JS
以下钩子文件直接输出大段 CSS 和 JS,未分离到独立样式文件:
| 插件 | 文件 | 问题 |
|---|---|---|
| announcements | hook/announcements_display.php | 内联 CSS+JS 滚动公告 |
| friend_links | hook/home_sidebar_bottom.php | 内联 CSS 约 27 行 |
| invite | hook/layout_head_end.php | 内联 CSS+JS 注入注册页 |
建议:将 CSS 移到 assets/style.css,JS 移到 assets/script.js,保持钩子文件干净。
1.4 无 uninstall() 方法或 uninstall() 不完整
| 插件 | 问题 |
|---|---|
| red_packet | plugin.json 中无 activated 字段,但插件不依赖 Plugin.php 的激活/卸载流程 |
| daily_checkin | uninstall() 只删 daily_checkin 表,没清理 users.points 字段和 settings 表 |
| content_review | uninstall() 可能未清理 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.php560 行,未完整审阅,但已知:- 路由使用
require_once引入控制器(冗余) - 插件已禁用(
activated: false) Plugin.php和AdminController.php未审阅
建议:启用前需完整测试。
2.11 积分红包 (red_packet) ⚠️ 有改进空间
问题:
RedPacketController.php487 行,建表逻辑在控制器中而非插件激活钩子中: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 处理方式 |
最快可修复的问题(按优先级):
- 删除 6 个残留备份文件
- 修复
dev_docs的命名空间大小写 bug - 修复
seo的自定义头代码转义问题 - 给各插件资源路径加
BASE_PATH