漏洞概述
Lazy Blocks 是一款 WordPress Gutenberg 插件,允许用户通过可视化界面创建自定义块,并支持在块模板中直接编写 PHP 代码作为渲染逻辑。
近期,网宿安全演武实验室监测到,该插件存在远程代码执行漏洞。该漏洞的核心问题在于对用户输入缺乏严格的类型检查与过滤,特别是在 REST API 接口及自定义块构建器模块中,导致已认证用户可通过构造恶意参数触发代码执行。(网宿评分:高危、CVSS 3.1 评分:8.8)
目前该漏洞POC状态已在互联网公开,建议用户尽快做好自查及防护。
受影响版本
Lazy Blocks <= 4.2.0
漏洞分析
从危险函数出发,classes/class-blocks.php这里有一个显眼的eval
$code直接拼进eval,没有任何过滤。接着思考$code能不能被外部控制?
全局搜索php_eval的调用,只有一处,位于render_callback():
触发条件很清晰,需要同时满足两点:
- $code['output_method'] 等于 'php'
- $code[$custom_render_name] 有值,这就是最终传入eval的内容
继续往上追,$code从哪来:![]()
$block['code']在marshal_block_data_with_controls()里组装:
继续搜索marshal_block_data(封装了marshal_block_data_with_controls)的调用方,找到classes/class-rest.php的 block_builder_preview:

这个接口的作用在于,用户在后台编辑块时,编辑器调它来即时看效果,所以它接收的是还没存库的原始配置,直接走渲染流程。导致code_output_method和code_editor_html会原样流入marshal_block_data,最终到达php_eval,全程没有经过数据库,所以也不经过任何保存时的校验。
那么触发这个接口需要什么权限?
显然,请求里不带post_id时,系统只检查edit_posts。而WordPress里的Contributor角色默认就有edit_posts,即注册用户就能申请到的最低编辑权限。
漏洞复现

修复方案
目前官方已有可更新版本,建议受影响用户升级至最新版本:
https://wordpress.org/plugins/lazy-blocks/
产品支持
网宿全站防护-WAF已支持对该漏洞利用攻击的防护,并持续挖掘分析其他变种攻击方式和各类组件漏洞,第一时间上线防护规则,缩短防护“空窗期”。
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf
客服小蜜蜂(微信:freebee1024)


