说明:本帖由我本人(350)撰写并发布。全部分析为逐行通读核心源码、逐项人工核验,每条结论均附行号,非自动化批量扫描。审计对象为官方「源码下载」提供的 bbs1org.zip(v8.6.5),范围:index.php(3316 行)+ app/optional/Setup.php、Plugin.php、Cron.php + app/assets/index.js;不含 app/plugins 插件(插件侧已另有全站插件审计帖,见主题 828,本文不重复)。
总体结论:核心安全基线在同体量单文件项目中属于上游——SQL 全参数化、输出统一转义、CSRF 全 POST 覆盖、会话签名规范、权限分层完整,未发现可直接利用的 SQL 注入、存储型 XSS、越权、SSRF 或开放重定向。问题集中在「防护缺失」类与若干边界场景,按严重度如下(行号对应 v8.6.5 源码)。
🔴 高危
1. 登录/注册无内置防爆破限速。 security.rate_allow / security.rate_hit 两个 hook 核心没有默认实现,未安装限速插件的站点对撞库、刷号零防护(index.php:2596-2607、2269、2341)。建议核心内置失败计数 + 递增锁定,按「IP+用户名」双维度,并配合第 3 条的可信 IP 解析。
2. 安装器无认证、无一次性密钥。 install.lock 仅按「文件是否存在」判断:未完成安装的新站,任何访客可抢先访问 ?a=install 完成安装、自建管理员(完整接管);管理员删除锁文件准备重装期间,安装器命中「已安装」数据库时会走 i_restore_existing_install,用攻击者提交的配置覆盖 app/data/db.php,把数据后端指向攻击者控制的数据库(Setup.php:276-285、248-254;index.php:3283-3285,且在全局 check() 之前分发)。建议安装向导绑定一次性密钥(环境变量/本地文件)或仅限本机访问。
🟠 中危
3. IP 可伪造。 ip_addr() 无条件信任 HTTP_CLIENT_IP / X-Forwarded-For 等请求头,且优先级高于 REMOTE_ADDR(index.php:756-765)。IP 维度的限速、封禁、审计日志均可被任意伪造(还能把他人 IP 写进日志制造假证据)。建议仅在 REMOTE_ADDR 命中可信反代地址段时才解析前置头。
4. cron 入口无鉴权。 匿名 GET ?a=cron 即可触发 cron_run() 执行所有到期插件任务(Cron.php:205-214;index.php:3270;站点关闭时 cron 仍在放行白名单,index.php:1475)。租约机制防止了并发重复执行,但攻击者仍可强制触发任务、消耗资源、观察任务名与成败。建议仅允许 CLI,或要求共享密钥 token + hash_equals 校验。
5. Host 头注入。 未配置 site_base_url 时,base_url() 直接采用 HTTP_HOST 生成 canonical 等绝对 URL(index.php:2370-2376、2377-2393),可被用于 SEO 投毒、缓存投毒。建议对 Host 做白名单校验,或强制配置 site_base_url。
6. 密码策略过弱。 注册密码最小仅 4 位(index.php:28、2257-2260);安装器管理员密码只查非空、无强度要求(Setup.php:305-308)。叠加第 1 条,弱口令被爆破风险高。建议最小 8 位 + 复杂度提示。
7. 禁言用户仍可发私信,且私信无限速。 user_notify_page 仅 need_login、不走 need_speak,也没有频率限制(index.php:2346-2369):被禁言用户可继续私信,任何人可高频群发骚扰。建议加 need_speak 与发送频率限制。
8. tab_bar_html() 的 label/class 未转义。 index.php:1240-1247 中 label 与自定义 class 直接拼接进 HTML。核心调用方目前是硬编码字符串,但 user.profile_tabs / admin.tabs / topic.index_tabs / top.menu_links 等 hook 返回的 label 会原样进入 HTML,插件一旦携带用户可控内容即构成存储型 XSS。建议统一 h()。
9. 用户名枚举。 注册返回「用户名已存在」、用户主页对不存在用户名返回 404(index.php:2323-2324、2654-2658)。登录接口已统一为「用户名或密码错误」(做得好),注册与主页仍可枚举。
🟡 低危 / 加固建议
10. 主题页 p 参数无上限,可构造超大 OFFSET 慢查询(index.php:1592 明确跳过 topic、2938-2939、2897 SELECT *),轻微 DoS 面;与下面性能部分合并处理。
11. GET 副作用:打开通知页即全部标记已读(index.php:2835-2836)、浏览量 GET 自增(2915-2918,已有 Cookie 去重),影响轻微。
12. opcache_refresh 为公开 GET 路由,仅靠锁文件存在(index.php:786-795),锁文件残留时任何人可反复触发 opcache 重置。建议 need_admin + POST + CSRF。
13. 安装器数据库连接错误原文回显,泄露 DSN/host/库名(Setup.php:233-240);安装完成页明文回显管理员密码(Setup.php:255-259)。建议通用错误 + 服务端日志,密码改为「复制一次」交互。
14. 全站无 CSP / X-Frame-Options / X-Content-Type-Options(index.php:2091、1497-1504);JSON 无 XSSI 前缀。输出转义本身完整,风险低,建议补安全响应头。
15. 插件市场安装:缺省 sha256 时客户端自行哈希当「期望值」,校验形同虚设(Plugin.php:207、237);市场安装不校验 PHP 语法,与上传路径不一致(Plugin.php:225-273 vs 1138),语法错误插件可能导致请求级白屏;ignore_ssl_errors 可全局关闭出站 TLS 校验(Plugin.php:111-114)。均为后台侧加固点。
16. JS 侧 innerHTML 汇点信任服务端 HTML(index.js:59、233、553、561),核心数据源均经 h()/markdown_html 转义,当前无 XSS;插件若返回 data.modal.html 需自行转义。
17. 会话 TTL 180 天(index.php:29)、无设备列表(改密码可吊销);app/data/db.php 明文存数据库口令(有 APP_ROOT 守卫,属常见设计,注意目录权限与备份)。⚙️ 性能与架构(重点)
- **发主题即全表 COUNT(*)**:home_stats_refresh_topics 每次发帖执行 SELECT COUNT(*) FROM app_topics(index.php:1345-1349、2502)。建议与 stats_replies 一样改用 MAX(id) 或维护计数器。
- refresh_topic_stats 一次 3 个关联子查询(index.php:2253-2256):COUNT + 两次取最后回帖。可合并为一次子查询。
- 搜索 LIKE '%..%' 全表扫描兜底(index.php:1957-1960、1992-1999):短词或未建 FTS 时对 LONGTEXT 全表扫描。MySQL 建议确认 ngram 全文索引已建(Setup.php:149-152),SQLite 用 trigram(3 字符以上已自动走 FTS,做得对)。
- 回帖软删除不维护计数:del('replies') 只清 body,不更新 reply_count/last_reply_at/last_reply_user_id(index.php:2572-2577),楼层号、分页、「暂无回复」空态会失真。建议删除后调用 refresh_topic_stats。
- 删用户无 LIMIT 取全部回帖并逐主题刷新(index.php:2570、2582-2584),高发帖用户删除时产生大结果集 + N 次多子查询 UPDATE。建议批量合并刷新。
- 搜索节流复用 last_post_at(index.php:2790-2794、770-776):搜一次会重置发帖冷却,反之亦然。建议独立字段与独立频率。
- 次要项:create_notification 非事务(932-934);注册同名 TOCTOU,唯一约束兜底但报错不友好(2323/2338);@提及逐条插入通知(997-999);cut() 对多码点 emoji 可能截半(1570-1575);通知列表 SELECT * 拉 LONGTEXT(1011);头像依赖外部 DiceBear 服务,存在可用性与隐私依赖(1738-1749);通知链接递归正则 (?R)(1056);MySQL FORCE INDEX 硬编码索引名(2725)。
✅ 亮点(客观记录,值得肯定)
- SQL 注入防护到位:全程 prepare/execute 绑定,PDO 仿真预处理关闭(81);表名/列名白名单(app_db_identifier:92-96);LIKE 用 ESCAPE '!' 且正确转义 % _ !(1957-1960);FTS 查询双引号转义(1921);排序/字段全白名单(2668-2672、2724、2896)。
- XSS 防护覆盖面广:h() 统一转义(267-270),富文本默认「转义+换行+提及链接」,核心无 raw HTML 直出(1843-1852);highlight_style、头像、title/meta、canonical 均转义。
- CSRF 规范:全 POST 统一校验 double-submit token + hash_equals(1479-1488、3295);登出/删除等状态修改仅 POST。
- 会话健壮:uid.expire.hmac(passwd_hash 为密钥)+ 恒时比较 + 过期校验(349-363、1375-1402);改密后旧会话自动失效;Cookie HttpOnly + SameSite=Lax + 条件 Secure(335-338)。
- 授权完整:need_admin/need_manage/can_manage_topic/can_manage_reply 分层清晰;后台所有入口 need_admin;他人通知页 own_profile 校验(2777);禁删 uid=1、禁删自己(2467、2564)。
- 在线升级系统设计好:固定升级源 + sha256 文件清单 + 逐文件哈希校验 + 原子替换 + 回滚 + 路径穿越白名单(Setup.php:480-540、718-808);升级/迁移入口内部自鉴权(Setup.php:1121、1135、1593)。
- 数据层工程质量高:SQLite WAL + busy_timeout + BEGIN IMMEDIATE 抢占写锁(83-90、311-330);批量 IN 查询无 N+1(376、395);请求级 + 持久化缓存体系且写后失效正确(445-475);索引覆盖精准(Setup.php:132-158);事务粒度正确。
- 错误处理与信息泄露控制好:display_errors=0;异常详情仅 uid=1 可见(3308-3314);SQL debug 仅 uid=1 且默认关闭(2143);数据库错误对普通用户脱敏(1556-1565)。
- 插件系统防御面好:全库无 unserialize/eval/shell_exec;上传插件有 is_uploaded_file + 2MB 上限 + 语法校验 + 符号链接拒绝(Plugin.php:1128-1163);卸载防穿越;manifest 回调名白名单(638-695);插件异常自动停用。
修复优先级建议
- P0:核心内置登录/注册限速;可信代理 IP 解析;安装器一次性密钥;cron 入口鉴权。
- P1:密码策略(≥8 位);私信限速 + 禁言校验;tab_bar_html 转义;Host 白名单/强制 site_base_url;主题页分页封顶或游标分页。
- P2:其余低危项与性能优化(软删除计数、refresh_topic_stats 合并、COUNT 改 MAX 等)。
以上全部附源码行号,欢迎逐条核对。@bbs1org 请站长过目,也欢迎各位大佬指正讨论。
主楼- bbs1org2026-08-18
内核是最简版本,上述限速等缺陷需要安装插件实现
关注一下,这些应该都需要插件实现,内核似乎很简洁。
- bbs1org2026-08-18
- bbs1org2026-08-18
越简单越安全
- bbs1org2026-08-18
禁言用户仍可发私信,且私信无限速。这个我后续优化
- 1234567892026-08-18
ai确实牛逼,很多问题一次性全部知道了😀