[修复]全盘审计报告与修复计划(2026-08-16 / 08-18 两轮)

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

本文由 FlintHub 开发文档归档发布。原始文档日期见标题前缀,来源:合并篇(见正文内 merged_from 列表)。

全盘审计报告与修复计划(0816 / 0818 两轮)

本篇由 4 篇原始文档合并去重而成:两轮审计各含「计划 + 报告」。两轮均为只读审计(未修改任何代码/数据/配置,对拍脚本用后即删),审计人 AtomCode(deepseek-v4-flash)。

一、审计背景与方法

项第一轮(08-16)第二轮(08-18)
依据全盘审计计划六阶段流程 + 三份交接文档(P14/P25/P26)十二节框架 + 《PHP代码安全审计完整维度》
审计范围flinthub 程序本体仅程序本体(根目录入口 / app/ / assets/ / cli/ / plugins/ / data/ / protected/);update/ 不审
基线V1.0.0,PHP 8.0.2 / SQLite 3.33.0(无 RETURNING)/ phpstudy + Nginx;用户 50,008 / 版块 7 / 博客 5同左(数据规模复用上轮基线快照)
数据基线topic_index 192,111;reply_index 160,753;search_index 4 季度合计 2,357,922 行;当前季度 32 桶(topic 26,282 / reply 21,960)同上
语法全量 php -l app/ 0 错误沿用上轮结论,本轮只读未改动
镜像一致性fc /b 抽查 6 个文件全部逐字节一致未重复

二、第一轮(08-16)

2.1 总览

合计:0 严重 / 1 中 / 6 低 —— 无致命问题,核心六维全部达标。中等问题 1 项(缓存键页码未钳制,可被刷缓存文件)。

维度结论问题数(严重/中/低)
代码安全✅0/1/4
数据一致性✅0/0/0
性能✅0/0/1
兼容性✅0/0/0
功能回归✅0/0/0
部署交付✅0/0/1

2.2 问题清单(7 项)

#级别维度位置问题修复建议
1中性能/安全ForumController.php:35,183,221缓存键页码未钳制到 totalPages:$cachePage = max(1, min(100000, page)) 用于缓存 key,而查询用钳制后的 $page。恶意游客遍历 ?page=1..100000 可生成最多 10 万个缓存文件(累计可达数 GB),磁盘 DoS + 缓存污染✅ 已修复(P27):render 写盘键改用钳制后的 $page;首页缓存键固定 home_1;总量封顶 totalPages
2低代码安全Admin/ThreadController.php:87 + Views/admin/threads.php:79帖色 color 字段无格式校验:后台直接入库,视图进 style="color:...";$this->e() 不做 CSS 语法拦截,red; background-image:url(javascript:...) 可注入(仅管理员可设置,账号失陷时放大为 XSS)入库前白名单校验 ^#[0-9a-fA-F]{3,8}$ 或预设色名,非法回退空串
3低代码安全app/Helpers/Upload.php:58-61finfo 不可用时 MIME 静默降级:仅靠扩展名白名单放行,polyglot 文件在 Nginx 未禁 PHP 执行时有解析风险finfo 缺失时图片类拒绝;或部署时禁 uploads 目录 PHP 执行
4低性能app/SplitDB/ViewCounter.php:53-85flush() 每请求 shutdown 跑 BEGIN IMMEDIATE + 全量遍历 APCu 键;键堆积时 flush 耗时,且在 main_index 写路径上加写锁可接受(apcu_dec 归零不重复处理);若线上有锁竞争可节流至 30s
5低代码安全app/Helpers/RateLimiter.php:153remaining() 标 @deprecated 且无调用方,死代码审计后删除(连同私有 buildKey)
6低部署交付assets/css/admin.css(.pagination/.page-dots)后台分页旧样式死代码:P26 已统一为 mn-pagination,旧类无引用可选清理,保留亦无风险

2.3 通过项(第一轮关键验证点)

  • 代码安全 C1~C10 全部通过:全站 PDO 参数绑定(IN 子句全部 intval);grep echo $_GET/POST/REQUEST/COOKIE 于 app/Views/ 0 命中;全部 POST 端点逐一核对 CSRF;CSS 注入走 Content::sanitizeCssStyle() 五属性 + 值字符白名单 + 危险模式拦截;越权防护含后台 30 分钟二次密码验证 + PostController::create 二次校验 canPost/canAttach;上传 9 类扩展名白名单 + finfo 严格匹配 + 5MB + random_bytes 随机名 + >5000px 像素炸弹防护 + Imagick 禁 SVG/MSL/MVG。
  • 数据一致性 D1~D8 全部通过(实测):桶 topic 总数 192,111 = topic_index 行数 192,111;reply 160,753 = 160,753;extern_path 空值 = 0;topic_index.bucket_path 空/非法 = 0;统计缓存永久化 JSON(防 unserialize RCE)+ 六个写入点主动失效。
  • 性能 P1~P8 通过(实测):keyset 深翻页稳态 0.171ms / 0.121ms(首测 15.459ms 为冷 WAL/杀软首触);OFFSET 对照 239,000 行 = 481.695ms(已知慢路径,仅页码数字直达);getIndexPaginated 走复合索引 SCAN ... USING INDEX idx_topic_index_list,无全表扫描、无 TEMP B-TREE(P25 覆盖索引误选教训未复发);统计 GROUP BY 78.282ms / 7 分类,缓存命中 ~2.14ms。

三、第二轮(08-18)

3.1 与第一轮的差异

  • 范围从"程序本体"进一步明确为六个具体区域,且显式排除 update/。
  • 维度从六维扩到十一节(新增:输入源、业务逻辑、会话/Cookie/安全头、文件上传、第三方 & CLI、配置/错误/日志、模板/视图/htmx、社区功能面/备份导出)。
  • 重点转向"部署与入口层"——这是与第一轮最大的不同:第一轮没查 Web 服务器层,第二轮发现 3 个高危全在这里。

3.2 总览

维度结论问题数(高/中/低)
架构与入口⚠️2/1/2
输入源✅0/0/1
代码安全✅0/1/1
业务逻辑✅0/0/0
数据层 & SplitDB✅0/1/0
会话 / Cookie / 安全头✅0/0/0
文件上传✅0/1/0
第三方 & CLI⚠️1/1/1
配置 / 错误 / 日志✅0/1/1
模板 / 视图 / htmx✅0/0/0
社区功能面 / 备份导出✅0/0/0

合计:3 高 / 6 中 / 6 低。结论:可上线,但须先处理 3 个高危项。

3.3 高风险问题(3 项,全部当日修复)

#问题证据修复
1(高)cli/ 目录可 Web 直访执行诊断/冒烟脚本直访会输出内部路径、tokenize 结果、库统计Nginx 增加 cli/ deny + plugins/[^/]+/data/ deny(泛化覆盖 16 插件)+ assets/uploads/*.php 禁执行;同时新增 cli/_guard.php(PHP_SAPI !== 'cli' → 403),33 个 cli 脚本在加载框架前 require,probe_page_cache.php 单独插入
2(高)插件 SQLite 库可被下载plugins//data/.sqlite 无 Web 防护Plugin::db() 自动为插件 data/ 目录补写 .htaccess(Apache deny)+ web.config(IIS hiddenSegments),幂等;存量 15 插件目录用一次性脚本补齐(用完即删)
3(高)upgrade_p41.php 无鉴权可触发升级脚本 Web 可直访问Web 访问要求管理员会话(Auth::isAdmin,异常一律 403),CLI 执行不受限

3.4 中等问题(6 项)

#问题修复
4cron_trigger.php 无可选触发密钥增加 CRON_KEY 常量校验(非空时 hash_equals 比对 ?key=,留空兼容旧部署)
5finfo 不可用时图片类未拒绝图片类(jpg/jpeg/png/gif/webp)拒绝,非图片保留扩展名兜底
6RateLimiter 缓存 unserialize 反序列化面缓存读写改 json_encode/json_decode(旧 serialize 缓存自动失效覆盖)
7DBFactory::foreign_keys = OFF 策略未标注决策标注:分片跨库外键不成立 + 业务显式清理已走查确认 + 开启需重排删除顺序
8反代/CDN 场景 Host 头注入SITE_URL 支持环境变量 FLINTHUB_SITE_URL / SITE_URL_OVERRIDE 覆盖
9数据库备份无限堆积自动轮转:仅保留最近 BACKUP_KEEP=10 份完整备份(realpath 校验后删最旧)

3.5 低危问题(6 项)与处置

AuditLog::getClientIp 信任 XFF 首 IP(部署标注,不影响鉴权/限流);Permission::canAttach 列缺失时默认放行(改为拒绝,且列检测从 MySQL 语法的 SHOW COLUMNS 改为 SQLite 兼容 PRAGMA table_info——原写法在 SQLite 下恒 false,本身就是隐患);install.php 安装完成后返回 410 Gone 并移除 .install_done 路径提示;{:raw} 原始输出点在 Views 中 0 使用(维持,新增必须过 Content::sanitizeHtml);CSP 含 unsafe-inline/unsafe-eval(取舍标注,htmx/Alpine 运行必需);ViewCounter::flush 改 30s 节流。

3.6 第二轮通过项(与第一轮一致且无回退)

代码安全六维(SQLi/XSS/CSRF/越权/SSRF/命令)全部通过,且上轮新增点复核无回退。核心业务链路防护完备:dummy hash 防枚举、DB 级登录锁定、30 分钟二次验证、SSRF 逐跳校验、zip-slip 防护。业务逻辑 D1~D7、会话/安全头 F1~F4、模板 K1~K3、备份导出 S6 均通过。

四、两轮对比

维度第一轮(08-16)第二轮(08-18)
发现问题0 严重 / 1 中 / 6 低3 高 / 6 中 / 6 低
风险主战场代码逻辑层(缓存键)部署/入口层(cli 直访、插件库可下载、升级脚本无鉴权)
高危数03(全部为配置/文件放置类,修复成本 <10 分钟)
修复落地P27 修复缓存键当日完成 15 项修复(3 高 + 6 中 + 6 低中的低危项),php -l 全过
共同结论代码安全六维通过,无致命问题同左,且第一轮新增点复核无回退

两轮共同暴露的系统性问题:

  1. "代码层安全、部署层裸奔" —— 程序本体的注入/XSS/越权防护明显高于一般 PHP 社区程序,但 Web 服务器层(Nginx deny、SAPI 守卫、插件数据目录防护)此前没有针对性配置,三个高危全在这里。第二轮补齐了 cli/_guard.php 与自动写 .htaccess/web.config 的机制。
  2. SQLite / MySQL 语法误用隐患 —— Permission::canAttach 用 SHOW COLUMNS 在 SQLite 下恒 false,导致权限列检测失效;同类问题提示"从 MySQL 迁移过来的代码需逐处核对方言"。
  3. "退役表"读路径反复出现 —— 第一轮的缓存键、第二轮的 CLI 与上传,都指向同一类问题:迁移后旧路径没有系统清理机制。这一项在 09-02 全量审计中演变为最严重的附件下载权限绕过(见《2026-09-02 全量代码审计与四批次修复实施报告》)。

五、修复执行情况(第二轮,2026-08-18)

项内容结果
1(高)Nginx deny + cli/_guard.phpnginx -t 通过;cli/ 38 文件 php -l 全过
2(高)Plugin::db() 自动写防护文件php -l 通过;15 插件 data/ 目录已补齐
3(高)upgrade_p41.php 管理员会话校验php -l 通过
4~9(中)cron 密钥、finfo 拒绝、RateLimiter json、外键标注、SITE_URL 覆盖、备份轮转均 php -l 通过
10~15(低)XFF 标注、canAttach 拒绝 + PRAGMA、install.php 410、CSP 取舍标注、flush 30s 节流、诊断脚本随 deny 一并解决均 php -l 通过

有意保留的取舍: CSP unsafe-inline/unsafe-eval(htmx/Alpine 必需,XSS 由服务端转义兜底);前置静态缓存仅游客命中;AuditLog XFF 仅影响日志展示。

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

全部回覆 (0)

暫無回覆

請 登入