[pow]浏览器算力校验码热
- 浏览器算力校验码ID pow版本 1.0.12插件制作者 idc免费739 行 / 39.4 KBHook / 路由 / 后台页在登录、注册、发帖和回帖前进行浏览器算力校验,抵御自动化滥用。app/plugins/pow/plugin.php开发日志最新 10 条
个人独立维护项目。
主楼 插件质量报告
插件:
powHook 功能范围 循环 使用频率 文件读写 修改系统表 读写系统表 读写自己的表 login.before_submit 登录表单提交前 否 3 - - - 写 plugin_pow_used, plugin_pow_fails, plugin_pow_stats login.form_extra 登录表单 否 3 - - - 读 plugin_pow_fails register.form_extra 注册表单 否 3 - - - 读 plugin_pow_fails reply.before_save 回帖发布/编辑表单提交 否 3 - - - 写 plugin_pow_used, plugin_pow_fails, plugin_pow_stats topic.before_save 主题发布/编辑表单提交 否 3 - - - 写 plugin_pow_used, plugin_pow_fails, plugin_pow_stats user.before_save 用户注册/资料保存前 否 3 - - - 写 plugin_pow_used, plugin_pow_fails, plugin_pow_stats reply.form_extra 回帖编辑表单 否 2 - - - 读 plugin_pow_fails topic.form_extra 主题发布/编辑表单 否 2 - - - 读 plugin_pow_fails 颜色说明:黄色表示有数据读写,红色表示 Hook 在系统循环中执行,浅蓝色表示有文件写入。“列表跳过”表示回调在列表路径会提前返回,“回调内”表示操作位于回调自身或其帮助函数的循环体内。“文件批处理”表示逐个处理用户一次提交的文件,属于必要操作,不标记修正。只有操作实际处于需要优化的循环路径时,才会标记“修正❗️”。
数据字典
plugin_pow_stats字段 类型 可空 默认值 约束 stat_date key 否 - 主键 action key 否 - 主键 count uint 否 - - fail_count uint 否 0 - plugin_pow_used字段 类型 可空 默认值 约束 proof_hash key 否 - 主键 used_at uint 否 - - plugin_pow_fails字段 类型 可空 默认值 约束 id id 否 - 主键、自增 ip key 否 - - failed_at uint 否 - - 版本 1.0.0 更新:
首次发布:登录、注册、发帖、回帖前完成工作量证明,抵御自动化刷号与灌水啥是工作量?
体验不错。防御力如何?
版本 1.0.1 更新:
优化了下移动端的显示版本 1.0.2 更新:
修复:验证通过,提交的时候,按钮状态又变成了需要验证,但是不影响提交。验证一下via浏览器是否无法使用吗?
版本 1.0.3 更新:
修复WebView 内核较旧时整个脚本语法解析失败导致验证按钮完全无反应改个插件中文名吧。太技术,站长不明白。比如叫:浏览器算力校验码
改个名字吧,我之前想做的的没弄,名字叫:无感人机验证
点保存时会报错:HTTP ERROR 444
版本 1.0.8 更新:
新增
验证码样式与输入框对齐(单列布局、宽 450px)
快速回复面板:验证码与回复按钮同行
兼容 danmaku_react:弹幕选项单独一行,不挤占布局
移动端自适应(≤640px 单列)
修复
登录/注册页进度条"下划线"(hidden 失效)
进度条填充错位、过长(限宽 340px)
验证通过后"验证通过"与"PoW"徽标错位、字号不一
提示文字阻断回复按钮布局其他
兼容新旧 HTML 结构与多插件共存
1.0.7
前后端难度统一(challenge 内解析)
难度上限 28 → 22
限频只计恶意失败,避免误封
proof 判重原子化,防重放
统计写入并发安全
清理死代码、修正密钥轮换最后由 idc 编辑于 2026-08-17 23:08测试测试一下
回复测试一下。
🔍 插件审查报告(对照《AI 开发规则》与开发者文档)
🔒 安全问题
未发现明显问题(挑战带 HMAC 签名、防重放唯一键、输入参数化,限频与权限/CSRF 均由核心保障)。
⚡ 性能问题
- 表单渲染时额外一次计数查询:plugin.php:137 pow_field_html → 108 pow_effective_bits 每次执行
val("SELECT COUNT(*) FROM plugin_pow_fails ...")。虽非红区 Hook,但每次登录/注册/发帖/回帖表单都多一次 DB 读,建议请求级缓存或并入限频预加载。
🐛 功能/规范缺陷
- 编辑主题/回帖时仍渲染 PoW 字段却不校验:165-173 无条件渲染,189/195 仅新建(id<=0)时校验,编辑页出现无效验证码。建议按 $ctx['editing'] 只在新建时渲染。
- 防重未走 app_db_insert_ignore():85-90 手工拼 INSERT IGNORE/ON CONFLICT;126 使用已废弃的 MySQL VALUES()。建议防重走封装函数,MySQL 用别名替代 VALUES()。
- cron 清理回调(277-289)无互斥锁,建议加锁保证并发安全。
✅ 修复优先级
- 编辑表单按 editing 条件渲染;2. 表单计数查询加缓存;3. 防重走 app_db_insert_ignore 并替换 VALUES();4. cron 加互斥锁。
- 表单渲染时额外一次计数查询:plugin.php:137 pow_field_html → 108 pow_effective_bits 每次执行
版本 1.0.9 更新:
⚡ 性能问题
表单渲染时额外一次计数查询:plugin.php:137 pow_field_html → 108 pow_effective_bits 每次执行 val("SELECT COUNT(*) FROM plugin_pow_fails ...")。虽非红区 Hook,但每次登录/注册/发帖/回帖表单都多一次 DB 读,建议请求级缓存或并入限频预加载。
🐛 功能/规范缺陷
编辑主题/回帖时仍渲染 PoW 字段却不校验:165-173 无条件渲染,189/195 仅新建(id<=0)时校验,编辑页出现无效验证码。建议按 $ctx['editing'] 只在新建时渲染。
防重未走 app_db_insert_ignore():85-90 手工拼 INSERT IGNORE/ON CONFLICT;126 使用已废弃的 MySQL VALUES()。建议防重走封装函数,MySQL 用别名替代 VALUES()。
cron 清理回调(277-289)无互斥锁,建议加锁保证并发安全。
✅ 修复优先级
编辑表单按 editing 条件渲染;2. 表单计数查询加缓存;3. 防重走 app_db_insert_ignore 并替换 VALUES();4. cron 加互斥锁。🔍 复核报告(v1.0.9,回应此前审查)· @idc
✅ 已确认修复
- 计数查询已加请求级缓存:pow_fail_count 用 static $cache 按 ip:window 缓存(plugin.php:60-68),每次请求只查一次——正确。
- 编辑页不再渲染 PoW:pow_topic_form/pow_reply_form 在 editing 时直接返回(plugin.php:188、194)——正确。
- 防重走封装 app_db_insert_ignore(plugin.php:105);MySQL 统计改用行别名 new.* 替代废弃 VALUES()(plugin.php:147)——正确。
- cron 加互斥锁 flock LOCK_EX|LOCK_NB(plugin.php:303-307)——正确。
❌ 新问题
- 重放判定有 1 秒窗口:plugin.php:104-107 以 now()(秒级)作 used_at 并靠 === $used_ts 判重,同一秒内重复提交同一 proof 时 insert_ignore 不插入、SELECT 读回同秒值 → 误判未使用。建议用唯一键冲突结果或非时间随机值判重(影响极小,同秒复用省一次计算)。
- manifest author 为域名形式(plugin.php:689),与署名 @idc 不一致,建议统一(规范要求 author 准确)。
其余:挑战 HMAC、难度从 challenge 解析、限频、参数化、need_admin 由核心 admin_page 兜底均正确;未发现明显安全/性能问题。
💡 顺带建议
管理页手写 is_post_request()(plugin.php:224)未用 require_post(),CSRF 已由核心 check() 全局校验(index.php:1485),无风险,建议统一。
总结:上一轮 4 项已全部修复,仅剩同秒重放判定与 author 署名两处小问题,插件基本干净。
版本 1.0.10 更新:
修复:重放判定有 1 秒窗口:plugin.php:104-107 以 now()(秒级)作 used_at 并靠 === $used_ts 判重,同一秒内重复提交同一 proof 时 insert_ignore 不插入、SELECT 读回同秒值 → 误判未使用。建议用唯一键冲突结果或非时间随机值判重(影响极小,同秒复用省一次计算)。
更新:manifest author。🔍 复核报告(v1.0.10,回应 1.0.9 版审查)· @idc
✅ 已确认修复
- 同秒重放:plugin.php:104-109 改 INSERT IGNORE / ON CONFLICT(proof_hash) DO NOTHING,以 rowCount()===0 判「已使用」,不再依赖 used_at 时间戳,原子防重。
- author 署名:691 行 'author' => 'idc'。
❌ 未生效 / 新问题
- 【兼容】149 行 MySQL 统计 INSERT ... VALUES(?,?,?,?) AS new ON DUPLICATE KEY UPDATE count=count+new.count,...:行别名 AS new 仅 MySQL 8.0.19+ 支持,MySQL 5.7 及 MariaDB 旧版会语法报错,而规则要求兼容 MySQL 全系。建议确认实际部署库版本,或退回 VALUES()(仅弃用、未移除)写法。
- 【功能/UX】pow_field_html(156-176)只判断 enabled_动作(159),未同步判断 logged_in_mode='skip' 与 admin_exempt;而 pow_guard_check(134-140)会跳过校验。已登录用户设「跳过」或管理员豁免时,表单仍渲染「开始验证」按钮(显示必填却实际不校验),易误导。建议渲染端与校验端共用同一豁免判断。
💡 顺带建议
pow_effective_bits(121-132)每次表单渲染都调 pow_fail_count,已加 request 级缓存(60-68),无 N+1。其余核验:挑战 HMAC 绑定 csrf_token()+pow_secret(44-49、99)、难度从 challenge 解析、防重、限频、参数化、need_admin 由 admin_page 兜底(index.php:3157)均正确;前缀/两参签名/hook 真实存在/description 均合规。
总结:上一轮 2 项已全部修复;仅剩 MySQL 行别名兼容性与「skip/豁免仍显示按钮」两处小问题,插件整体干净。
审计标准:站长发布的《插件开发 AI 规则》+ 开发者文档中心规范,安全/性能/功能/规范逐行人工核验,非批量自动化扫描。
版本 1.0.11 更新:
优化小细节版本 1.0.12 更新:
增加版本号版本 1.0.12 更新:
修复
- 提交失败(如登录密码错误)后再次提交提示「验证已使用」:proof 对同一 challenge 是确定性计算结果,提交失败后 challenge 未刷新导致重复 proof 被判重。现改为提交后自动刷新 challenge 并清空旧 proof。
🔍 插件审查报告(AI 自动审查,对照《AI 开发规则》与开发者文档;本插件未被 8/18 楼上 350 的报告覆盖,属独立首次审查)
插件:浏览器算力校验码(pow)v1.0.12
🔒 安全问题
未发现明显安全问题。⚡ 性能问题
未发现明显问题。🐛 功能/规范缺陷
规范一致性建议:后台管理页函数体内未见显式调用核心 need_admin()(依赖核心 admin_page() 路由层统一鉴权兜底,当前不构成越权);涉及写操作时判断请求方式使用手写的 $_SERVER['REQUEST_METHOD'] === 'POST',效果等价于核心 require_post(),但写法与站内多数插件不一致。✅ 修复优先级
低优先级:建议在后台页面函数内补充显式 need_admin()/require_post() 调用,作为纵深防御,避免未来核心路由调整时失去这层保护;不影响当前功能与安全性。

