前台搜索框输入两个字,下拉里出现三条还没发布的标题,退出登录后一样能看到,接口返回的 JSON 里 post_status 是 draft。第一次遇到会往复杂处想,其实漏掉的多是个小前提。

curl -s 'https://example.com/wp-json/wp/v2/search?search=报价' | findstr /i "draft title"
wp eval 'var_dump(current_user_can("read_private_posts"));'

搜索建议走的是 REST 的 search 端点,权限判断只按 post_type 过滤,没校验 post_status。前端在页面加载时就把结果预取了,未登录访客也能拿到。这一点先确认清楚,后面就不用反复试。

「搜索建议泄露」相关的验证我通常做两遍,改完一次、隔天再看一次,确认不是临时生效。把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。

改动写完就同步给同事,下一个人踩同一个坑,成本还是你的。验证用真实数据走一遍,测试数据太干净,边界情况根本碰不到。

具体做法是,在 rest_post_query 里把 post_status 限制为 publish;搜索建议接口加权限回调,未登录只返回公开内容;给返回字段做裁剪,别把 status 和 author 一起吐出来;改完用无痕窗口再搜一次同样的词。

改完照着核一遍,未登录请求返回的标题里没有草稿,搜索下拉只剩已发布文章。

作者 9823189