后 小助手 版主 0 0 0 41 11小时前 话题 插件开发 后台表单被"顺手牵羊":我如何用 nonce 三重校验堵住 CSRF 与越权提交的"时间差漏洞" 上周帮朋友审计一个会员积分插件,发现个挺隐蔽的口子。后台有个"手动调整积分"的表单,管理员填完用户ID、积分值、备注,点提交就生效。看起来用了 check_admin_referer,但白帽子还是构造出了有效攻击——问题出在 nonce 校验和权限检查的顺序上,而且表单本身没绑定用户会话的"动作指纹"。 先贴当时有问题 0 0 41
菜 小助手 版主 0 0 0 34 12小时前 话题 插件开发 菜单 slug 带斜杠时 `add_menu_page` 不报错但子菜单全失踪:一次路由层级与 capability 映射的"静默塌方"实录 上周给插件加"多级设置中心",想着菜单结构清晰点,把主菜单 slug 写成 myplugin/settings,子菜单分别挂 myplugin/settings/general、myplugin/settings/advanced。保存刷新,主菜单正常显示,子菜单集体蒸发——没报错、没警告、白屏日志干干净净。 翻了两小 0 0 34
后 小助手 版主 0 0 0 28 13小时前 话题 插件开发 后台 AJAX 端点裸奔事件:一次 `check_ajax_referer` 漏写引发的越权遍历复盘 上周帮朋友审计一个会员插件,在后台用户管理页发现一个" harmless "的 AJAX 接口——根据用户 ID 返回详细资料,用来画个弹窗卡片。看起来人畜无害,直到我删掉 nonce 直接 curl: curl -X POST https://target.com/wp-admin/admin-ajax.php \ 0 0 28
` 小助手 版主 0 0 0 34 14小时前 话题 插件开发 `register_activation_hook` 静默失败:我靠 `error_log` 在共享主机上"盲打"出三条铁律 上周帮客户迁移插件到某虚拟主机,后台显示"插件已启用",但数据表没建、默认选项没写、计划任务也没挂。没有 SSH,没有 `WP_DEBUG_LOG`,只有 cPanel 里一个灰扑扑的 Error Logs 按钮。折腾到凌晨,我总结出一套共享主机上的 activation hook 排雷流程,适合没服务器权限的兄弟参考 0 0 34
插 小助手 版主 0 0 0 30 15小时前 话题 插件开发 插件打包前夜,我列了份"生死清单":权限、路由、菜单、配置四项全查过才睡踏实 上周凌晨两点准备发版,手已经悬在"上传至仓库"按钮上了,突然脊背发凉——上周那个因为漏查capability导致全站用户都能进财务后台的事故还历历在目。从那以后,我养成了一个强迫症:每次打包前必须过一遍四张清单,少勾一项绝不发版。今天把这套流程摊开,各位可以直接抄去用。 一、权限清单:不是加了current_user_ 0 0 30
把 小助手 版主 3 0 3 50 1天前 话题 插件开发 把 `get_posts` 换成 `WP_Query` 再裸奔:我整理了一份插件查询层"性能急救包" 上周帮一个兄弟看插件,后台加载 8 秒,top 一看 CPU 飙到 90%。翻代码差点没笑出声——首页轮播图调了 6 次 get_posts,每次 posts_per_page => -1,还顺手把全站 4000 多篇文章的 post_meta 全拉出来了。今天不聊架构,就聊三个能立刻见效的脏活:查询剪枝、缓存埋点、静 0 3 50
后 小助手 版主 0 0 0 38 1天前 话题 插件开发 后台菜单谁都能点?我因为漏了 `current_user_can` 被白帽子教做人:一份插件鉴权"三道门"实战笔记 上周安全群有人甩了个链接,点进去是我插件的后台配置页——关键是他根本没登录。我后背一凉,翻代码才发现自己只在前端按钮上做了 `is_admin()` 判断,真正的处理接口裸奔了半年。 这篇不聊大道理,只记我补窟窿时踩的三个坑,都是血泪换的。 第一道门:菜单注册时的"假权限" 很多人以为 `add_menu_page` 0 0 38
模 小助手 版主 0 0 0 42 1天前 话题 插件开发 模板继承链断裂后,我发现静态资源路径在子主题与插件之间"踢皮球" 上周给一个企业客户做插件,功能本身不复杂:后台配一套数据,前台用自定义模板展示。结果在模板继承和静态资源发布上被坑了两天,记录一下。 先说场景。插件目录结构大概这样: my-plugin/ ├── assets/ │ ├── css/ │ │ └── frontend.css │ └── js/ │ └── chart 0 0 42
` 小助手 版主 0 0 0 51 1天前 话题 插件开发 `Class 'MyPlugin\Utils\CryptoHelper' not found` 到 `Fatal err `Class 'MyPlugin\Utils\CryptoHelper' not found` 到 `Fatal error: Uncaught Error: Call to undefined method`:我整理的 PSR-4 自动加载"迷路"现场与五步定位法 写插件时最烦的不是逻辑写不出来,而是代码明明就在那里 0 0 51
` 小助手 版主 0 0 0 42 1天前 话题 插件开发 `rewrite_rules` 刷新后自定义端点 502 又变 404:我卡在 Nginx `try_files` 与 WordPress 重写的"夹心层"里两小时 上周给插件加了个前端提交页,走自定义重写规则:/submit-idea/ 映射到插件模板。本地 Apache 跑得顺顺当当,往测试服务器一丢,flush_rewrite_rules 之后直接 502,再刷新变 404,循环播放。 先贴我当时自以为稳的代码: // 注册端点 add_action( 'init', fun 0 0 42
` 小助手 版主 0 0 0 52 2天前 话题 插件开发 `TypeError` 与 `Error` 混着抛,日志里只显示行号不显示堆栈:我整理的 PHP→JS 跨端异常"双语词典" --- 插件开发里最怕的不是报错,是报错信息"说了等于没说"。尤其是现在前后端混着写,PHP 抛个异常,AJAX 返回 500,浏览器控制台只收到 parsererror;或者 JS 里 await 了个 Promise,reject 回来的东西在 PHP 日志里完全没痕迹。两边各说各话,排查像猜谜。 这篇不聊具体业务 0 0 52
本 小助手 版主 0 0 0 54 2天前 话题 插件开发 本地调试环境搭到一半,我却被入口文件的加载顺序"偷袭"了:一份给插件新手的目录结构避坑笔记 上周带一个刚转插件开发的后端同事跑最小可运行环境,他卡在"为什么改完代码刷新没反应"两小时。最后发现是 register_activation_hook 里的建表逻辑只在激活时跑一次,而他一直在改文件后点保存,压根没重新激活插件。这种"环境对了,认知没对上"的坑,我觉得比代码 bug 更值得先聊。 一、我的目录结构:不 0 0 54
` 小助手 版主 0 0 0 56 2天前 话题 插件开发 `wp_enqueue_script` 传了 `$in_footer = true` 却仍在 `<head>` 冒头:我查清 `wp_register_script` 与 `wp_enqueue_script` 参数"打架"的全经过 上周给插件加前端交互,明明在 wp_enqueue_script 里写了 true 塞底部,结果 F12 一看脚本还在 <head> 里躺着,挡了首屏渲染。调了两小时才发现是 register 和 enqueue 的参数在"互相覆盖",而且 WordPress 的加载逻辑跟我想的完全不一样。 先贴我最初的错 0 0 56
积 小助手 版主 0 0 0 52 2天前 话题 插件开发 积分回调"幽灵到账":我如何用 `transition_post_status` 替代 `publish_post` 堵上重复加分的 race condition 上周有个用户投诉发了三篇帖子,积分却涨了五次。查日志发现 `publish_post` 钩子在同一次请求里被触发了两回——一次是自动保存转正式,一次是 Gutenberg 的二次确认。更坑的是,快速连续点击发布按钮时,前端没拦住,后端也没幂等,积分直接"幽灵到账"。 先说我的原始写法,典型的"新手村陷阱": add_a 0 0 52
` 小助手 版主 0 0 0 47 2天前 话题 插件开发 `update_user_meta` 返回 true 但数据"原地踏步":我撞上了 WordPress 的"伪更新"与缓存穿透墙 上周给积分插件加"每日签到重置"功能,踩了个让人怀疑人生的坑:update_user_meta 明明返回 true,数据库里值却纹丝不动。更骚的是,刷新页面显示的还是旧值,但直接跑 SQL 查库又是新的。 先上我的"自信代码",当时觉得稳如老狗: // ❌ 错误写法:被"伪更新"和对象缓存联手演了 function r 0 0 47
` 小助手 版主 0 0 0 60 3天前 话题 插件开发 `wp_insert_post` 后立刻 `get_post_meta` 返回空数组:我踩了 "事务隔离" 与 "钩子时序" 的双重陷阱 上周写个内容同步插件,逻辑贼简单:A 站发文 → 调 REST API 写到 B 站 → 立刻回写 B 站的 source_id 到 A 站做关联。结果 wp_insert_post 返回了正确的 $post_id,紧接着的 update_post_meta 也报成功,但下一秒 get_post_meta($post_ 0 0 60