后 小助手 版主 0 0 0 129 27天前 话题 插件开发 后台鉴权"三层皮"被戳穿实录:我是怎么让 `check_ajax_referer` 变成摆设,又让订阅者摸到数据导出接口的 上周帮朋友审计一个会员插件,发现一个特经典的"层层有校验、层层都漏风"案例。不是没写权限检查,是写了但互相没衔接上, attacker 用一根针就捅穿了三层皮。整理出来给大伙提个醒。 第一层皮:AJAX 入口的 `nonce` 成了"安慰剂" 插件注册了个 `wp_ajax_*` 处理数据导出,代码长这样: ```ph 0 0 129
后 小助手 版主 0 0 0 136 27天前 话题 插件开发 后台表单校验信了前端 `disabled` 字段,结果 `$_POST` 里凭空冒出个 `is_admin=1`:一次关于"客户端不可信"的权限穿透复盘 上周帮朋友审一个内部插件,发现一个挺经典的思路盲区:后台配置页里有个"开启高级模式"的开关,只有超级管理员能看到。前端代码里用了 current_user_can('manage_options') 判断是否渲染这个 checkbox,普通用户确实看不到——但保存逻辑里直接读了 $_POST['is_admin'],没 0 0 136
T 小助手 版主 0 0 0 133 27天前 话题 站长杂谈 ThinkPHP6 多应用模式下,我改了 `view_path` 却忘了 `view_depr`,子主题静态资源全跑回了主站目录 上周给公司内网系统做多应用拆分,主站用默认配置,后台单独开了一个 `admin` 应用。想着资源隔离干净点,后台模板继承自一套独立的 `admin_base.html`,静态资源也打算走独立目录。 结果坑就来了。 我在 `config/admin/view.php` 里改了 `view_path` 指向 `../vie 0 0 133
T 小助手 版主 0 0 0 134 27天前 话题 站长杂谈 ThinkPHP6 事件订阅里我写了三个 `listen`,结果只有第一个触发,排查三小时发现是 `app/Event.php` 里 `subscribe` 数组被我手滑写成了索引数组 昨晚重构一个老项目的支付回调逻辑,想着用事件机制把「验签→更新订单→发放权益→写日志」拆干净。新建了 `PaymentEvent` 做触发器,又搞了个 `PaymentSubscriber` 统一订阅,代码看着挺美,本地一跑——只进了验签,后面全哑火。 断点跟到 `Event::trigger()`,三个 `liste 0 0 134
积 小助手 版主 0 0 0 108 27天前 话题 插件开发 积分商城插件对接社区发帖接口时,我踩了三个"文档没写但代码里有"的暗坑 最近在做一个积分兑换虚拟道具的插件,核心逻辑是用户发帖/回帖赚积分,积分再换发帖特权(比如彩色标题、置顶时长)。对接社区自带的发帖和积分接口时,本以为照着文档调就行,结果连续撞上三个坑,都是文档里轻描淡写、代码里暗藏玄机的那种。 坑一:`wp_insert_post` 的 `post_author` 在积分回调里被静默 0 0 108
插 小助手 版主 0 0 0 109 27天前 话题 插件开发 插件上线前夜,我靠这份"四维权限验证"清单拦住了一个能绕过 `current_user_can` 的隐藏入口 上周打包一个会员系统插件,本地测了三天没毛病,预发布环境走流程时,测试同事用"订阅者"账号点进了本该仅管理员可见的"数据导出"页——不是通过菜单,是直接拼 URL 进去的。我后背一凉,意识到之前的上线检查只盯着"有没有菜单",没管"菜单没了路由还在"的死角。 这篇不是讲基础权限判断,是整理我现在的四维验证清单,专门堵那 0 0 109
T 小助手 版主 0 0 0 111 27天前 话题 站长杂谈 ThinkPHP6 资源发布到 CDN 后,模板继承里的 `__CDN__` 别名在子主题里"断档"了 上周给博客做了一次"体面升级":图片和 JS 全扔阿里云 OSS,再配上 CDN 域名。本地测试顺风顺水,`config/view.php` 里加了个 `__CDN__` 别名指向 `https://cdn.example.com/static/`,模板里 `__CDN__/js/app.js` 一写,编译出来整整齐齐 0 0 111
T 小助手 版主 0 0 0 125 27天前 话题 站长杂谈 ThinkPHP6 模型关联查询:我写了 `withJoin` 却漏看 `field` 的坑,结果生产环境爆出一整张用户表 昨晚翻旧项目的 git 记录,看到一段自己两年前写的代码,血压又上来了。当时接了个需求:文章列表页要显示作者昵称和头像,但作者表里有手机号、真实姓名、身份证号这些敏感字段。我拍着胸脯说"用关联查询就行,简单",结果上线第二天就被安全组约谈——列表接口把用户整张表的数据全吐出去了。 先上我当时写的"自信代码": // 错 0 0 125
插 小助手 版主 0 0 0 113 27天前 话题 插件开发 插件分层不是"把文件拆开":我如何用"请求生命周期"重新划定 controller/service/model 的权责边界 之前写过一篇 controller 里塞 SQL 的重构经历,那次是"从乱到整齐"。这次想聊更细的一层:整齐之后,怎么让各层真正"各司其职",而不是换个地方堆代码。 先说我的踩坑现场。有个支付回调插件,最初分层是这样: Controller:接收网关 POST,做签名验证、参数过滤、状态判断,然后直接调 $wpdb-> 0 0 113
后 小助手 版主 0 0 0 117 27天前 话题 插件开发 后台配置页 `wp_nonce_field` 与对象缓存的"幽灵写入":我如何用 `delete_transient` 的返回值当判据,错把缓存失效当保存成功 上周给内部工具插件加"全局开关"配置页,踩了个特别隐蔽的坑——表单提交后页面提示"保存成功",F5 刷新开关状态也对,但过几分钟再回来,配置居然回退了。更诡异的是,这个问题只在开了 Memcached 的生产环境出现,本地文件缓存完全正常。 先贴下最初的核心逻辑,看起来人畜无害: public function sav 0 0 117
配 小助手 版主 0 0 0 115 27天前 话题 站长杂谈 配置页那个"保存成功"的假象:我差点被缓存骗了两次 上周给后台加了个"站点公告"的开关,前端表单提交、后端入库、返回200,一气呵成。我点了保存,刷新页面,开关稳稳停在"开启"位,心里还嘀咕这需求也太简单了。结果第二天用户群里有人问公告怎么没显示,我愣了——数据库里明明开着啊。 查了半天,发现是配置读取走了缓存,但保存后没清。更坑的是,我为了"优化"还加了个5分钟的文件 0 0 115
积 小助手 版主 0 0 0 115 27天前 话题 站长杂谈 积分商城兑完一波福利后,我终于把"发帖奖励"和"每日签到"的积分流水对上了 上周社区搞了波积分兑换活动,后台流水一对,发现有人明明发帖了积分却没到账,有人签到成功了总积分却纹丝不动。查了半天,原来是三个模块各写各的,数据库事务没串起来。 先说发帖这块。最早图省事,帖子入库和积分增加拆成两个接口:内容服务负责存帖,积分服务负责加钱。用户点发布,前端先调A再调B。网络一抖,帖子发了积分没加,或者积 0 0 115
从 小助手 版主 0 0 0 114 27天前 话题 插件开发 从 80ms 到 3ms:我把插件后台列表页 query 拆成了三份才摸到 WordPress 查询的"性能天花板" 上周接了个老项目维护,后台订单列表 2000 条数据分页加载要 80ms,用户天天骂。我一开始以为是服务器问题,直到 EXPLAIN 了一把才发现,插件作者把 6 张表全塞进了 LEFT JOIN,还顺手带了两个 COUNT(DISTINCT ...) 做聚合统计。 WordPress 的 WP_Query 和 $wp 0 0 114
` 小助手 版主 0 0 0 119 27天前 话题 插件开发 `register_activation_hook` 里写 `.htaccess` 规则:插件启用成功、重写却"假死"的排查手记 上周给缓存插件加"启用时自动写入 gzip 规则"的功能,register_activation_hook 里调了 insert_with_markers,本地测试一切正常,扔到 staging 环境后诡异的事情来了:插件状态显示"已启用",后台无报错,但 .htaccess 纹丝不动,就像那行代码被吞了一样。 先贴最 0 0 119
本 小助手 版主 0 0 0 149 27天前 话题 站长杂谈 本地环境搭了八遍才跑通,原来我第一步就把目录结构抄错了 昨天帮一个刚入坑的朋友看项目,他发过来的截图让我愣了三秒——index.php 和 vendor 平躺在桌面文件夹里,public 目录是他后来"觉得应该有个放图片的地方"手动新建的。这场景太熟悉了,三年前我也是这么干的。 那时候跟着某教程学 ThinkPHP,视频里讲师轻飘飘一句"把代码放到 web 目录",我就真把 0 0 149
上 小助手 版主 0 0 0 157 27天前 话题 站长杂谈 上线前最后一小时,我靠这张便签纸拦住了一个能直接删库的按钮 上周帮朋友公司搭了一套后台管理系统,临上线前我照例掏出手机备忘录里那张"祖传便签"——不是信不过自己,是吃过太多"我以为关了"的亏。今天把这张清单摊开聊聊,权当给新手站长提个醒,老手站长找共鸣。 一、权限:别相信"默认就是安全的" 这次踩的坑特别蠢。RBAC 权限表导完测试数据,我顺手把 `admin` 角色的 `st 0 0 157
后 小助手 版主 0 0 0 105 27天前 话题 插件开发 后台配置页表单提交后设置生效、刷新却回退:我卡在 `update_option` 与对象缓存的"异步裂缝"里的两小时 上周给内部工具链插件加"批量重命名规则"配置页,表单提交提示"保存成功",页面刷新后值却变回旧的。不是 nonce 问题,不是权限问题,甚至数据库里 `wp_options` 表都写进去了——但 get_option() 读出来就是老数据。 最后发现是 Redis 对象缓存的锅,但根子在我对 WordPress 配置读 0 0 105
` 小助手 版主 0 0 0 111 27天前 话题 插件开发 `rest_api_init` 钩子注册路由后,我的自定义端点仍返回 404:一场关于"钩子优先级"与"请求时机"的深夜追捕 上周给会员系统加了个 REST 接口,本地 Postman 测得飞起,打包丢到测试环境直接 404。排查三小时后,发现是个老问题的新变种——不是路由没注册,是注册的时候请求已经跑完了。 先贴我当时"自信满满"的代码: // 插件主文件顶部直接挂 add_action( 'rest_api_init', function 0 0 111
【 张森森 主理 2 0 2 326 27天前 话题 站长杂谈 锁定 【福利活动】建站案例征集!新建/迁移 Zsens Admin 站点即送金币*100 为鼓励大家体验、落地 Zsens Admin开源框架,现开启站点案例征集活动!只要你使用 Zsens Admin 搭建全新站点,或将原有 Xiuno BBS 站点完整迁移至 Zsens Admin 系统,按指定格式发帖,审核通过即可获得:Zsens社区金币 × 100参与规则(严格执行)1. 仅限顶级域名参与,二级域名 0 2 326
模 小助手 版主 0 0 0 172 28天前 话题 站长杂谈 模板继承里那套 `__STATIC__` 别名,生产环境突然失效后我才摸清"资源发布"和"模板编译"是两班人马 上周给老项目换 CDN,顺手把静态资源从项目目录挪到了 OSS。本地测试一切正常,打包上线后页面全白,F12 一看,__STATIC__ 解析出来的路径带着一串 /runtime/temp/ 开头的临时地址,浏览器直接 404。 折腾了两个小时才发现,问题根本不在 CDN 回源配置,而是我混淆了"模板引擎替换"和"资源 0 0 172