EP01. "wp-security-review 安全审查"
🔒 登录后可标记已读- 插件上线前有没有认真查过 XSS、SQL injection、CSRF 这几个老问题?
wp-security-review就是拿这几条红线去扫你的 WordPress 代码,扫完直接给你行号、严重度和修法 - 这是
jorgerosal/wordpress-skills这个开源 skill 包里的其中一个,专门做 WordPress 主题/插件的安全代码审查,装进 Claude Code 后可以随时调用 - 核心是「三支柱模型」:输入尽早消毒(sanitize)、权限验证要有(nonce + capability)、输出要晚点转义(escape)——三根柱子有一根倒了就是漏洞
- 前置知识:先看过 Overview 系列的「Claude Code 是什么与新手上手」「进阶功能:Skills、Plugins 与 Routines」两篇,知道 Skill 是什么、怎么装
重点内容
这个 Skill 是做什么的
wp-security-review 是一套系统化的 WordPress 安全代码审查流程,不是简单丢个 prompt 让 Claude 「看看有没有问题」,而是照一套固定套路走:先抓 CRITICAL 级别的洞(公开代码的 SQL injection、没转义就输出的 XSS、状态变更操作缺 nonce),再抓 WARNING,最后才是 INFO 级别的加固建议,报告固定带行号、严重度、CWE 编号,还有「错误写法 / 正确写法」对照。
适合用在:
- 主题/插件的安全审计、上线前安全复查
- 有人通报了一个漏洞,要去代码里定位
- 审查表单处理、AJAX endpoint、REST API route
- 检查用户输入怎么处理、输出怎么渲染
不适合用在:
- 服务器加固/基础设施安全(Apache/nginx 设置、防火墙规则)——这个 skill 只看代码
- WAF(Web 应用防火墙)设置
- SSL/TLS 证书管理
- 纯性能审查(这个交给
wp-performance-review) - 跟 WordPress 无关的通用 PHP 安全问题
触发方式
装好之后有两种叫法,效果一样,看你习惯:
| 方式 | 写法 | 说明 |
|---|---|---|
| 斜线指令(完整版) | /wp-sec-review [path] | 完整审查,结果按文件、按严重度分组 |
| 斜线指令(快速版) | /wp-sec [path] | 只抓高风险问题,速度快,适合日常小改动后快速过一遍 |
| 自然语言 | 「审查这个插件的安全问题」「check this theme for XSS」 | 不用记指令,Claude 判断你的意图符合这个 skill 的 description 就会自动触发 |
📌 path 留空就是扫整个当前项目,也可以指定到某个文件夹,例如 /wp-sec-review wp-content/plugins/my-plugin。
严重度分级与判断上下文
| 严重度 | 定义 | 举例 |
|---|---|---|
| CRITICAL | 不用登录就能打、或会导致数据外泄/远程执行/权限提升 | 公开端点的 SQL injection、没转义的输出型 XSS、admin action 缺 nonce、文件上传没做权限检查 |
| WARNING | 要登录才能打、或需要特定条件 | 只有后台看得到的 XSS、登录后动作缺权限检查、输入消毒不完整 |
| INFO | 属于纵深防御,不是真的漏洞 | 没加 ABSPATH 检查、wp-config.php 没设安全常量 |
判断严重度时还会考虑场景:只有 admin 看得到的代码,严重度降一级;WP-CLI/cron 场景不需要 nonce(没有 CSRF 风险,因为不是走 HTTP 请求);REST API 用的是 permission_callback 这套权限模型,不是 nonce;面向公众的代码严重度维持最高。
按文件类型抓的坑
| 文件类型 | 主要检查项 | ||
|---|---|---|---|
| 插件/主题 PHP 文件 | 有没有 `defined('ABSPATH') \ | \ | exit;、eval()、exec()/shell_exec()、base64_decode($_...)、unserialize($_...)、include $_...` 这类危险写法 |
表单处理(admin-post.php) | 三步缺一不可:nonce 验证 → current_user_can() 权限检查 → 输入消毒 | ||
AJAX handler(wp_ajax_*) | check_ajax_referer()、权限检查、wp_ajax_nopriv_* 有没有配 CSRF 防护 | ||
REST API(register_rest_route) | 有没有 permission_callback(WP 5.5+ 强制要求)、写操作是不是误用了 __return_true | ||
数据库操作($wpdb->query 等) | 有没有用 $wpdb->prepare()、LIKE 查询有没有先过 esc_like() | ||
| 模板/输出文件 | 输出前有没有按情境用对转义函数(esc_html/esc_attr/esc_url/esc_js) | ||
| 文件上传 handler | 有没有用 wp_handle_upload() 而不是原生 move_uploaded_file()、有没有做 MIME 类型验证 |
实操示例:XSS 与 SQL Injection 的错法/对法
// ❌ CRITICAL:输出前没转义(CWE-79)
<h1><?php echo $_GET['title']; ?></h1>
<input value="<?php echo $user_input; ?>">
// ✅ GOOD:按情境用对转义函数
<h1><?php echo esc_html( $_GET['title'] ); ?></h1>
<input value="<?php echo esc_attr( $user_input ); ?>">
// ❌ CRITICAL:字符串拼接/内插直接进 SQL(CWE-89)
$results = $wpdb->get_results( "SELECT * FROM {$wpdb->users} WHERE ID = $user_id" );
// ✅ GOOD:一定要过 $wpdb->prepare() 加占位符
$results = $wpdb->get_results( $wpdb->prepare(
"SELECT * FROM {$wpdb->users} WHERE ID = %d",
$user_id
) );
// ❌ CRITICAL:admin_post 缺 nonce + 权限检查
add_action( 'admin_post_save_settings', function() {
update_option( 'my_setting', $_POST['value'] );
} );
// ✅ GOOD:nonce → 权限 → 消毒,三步一步都不能少
add_action( 'admin_post_save_settings', function() {
if ( ! wp_verify_nonce( $_POST['settings_nonce'] ?? '', 'save_settings_action' ) ) {
wp_die( 'Invalid nonce' );
}
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( 'Insufficient permissions' );
}
$value = sanitize_text_field( $_POST['value'] );
update_option( 'my_setting', $value );
} );
怎么安装
这个 skill 是 wordpress-skills 这个开源仓库(jorgerosal/wordpress-skills)打包的 18 个技能之一,安装一次,18 个技能一起到位,不用逐个装:
Claude Code:
| 方式 | 指令 | 适用场景 |
|---|---|---|
| 装进单个项目(推荐) | git submodule add https://github.com/jorgerosal/wordpress-skills.git .claude/plugins/wordpress-skills | 只想在这个项目用,团队成员 clone 项目就一起有 |
| 装到自己账号 | git clone https://github.com/jorgerosal/wordpress-skills.git ~/.claude/plugins/wordpress-skills | 所有项目都能用 |
| 只装这一个 skill | cp -r claude-skills/wp-security-review ~/.claude/skills/ | 只想要安全审查这一个功能,不要其他 17 个 |
装完重启 Claude Code,进到一个 WordPress 项目里跑 /wordpress-skills:wp-sec-review 验证有没有装成功(用 marketplace/submodule 方式装的话,指令前面会带插件命名空间 wordpress-skills:;用「只装这一个 skill」的方式则不带命名空间,直接 /wp-sec-review)。
Claude Desktop / claude.ai: 走 Settings → Capabilities → Skills,上传技能文件夹(把 claude-skills/wp-security-review 这个文件夹打包上传,里面要包含 SKILL.md)——跟 Claude Code 的 git submodule/marketplace 安装方式不同,Desktop 端是手动上传 UI,装好之后同样能用自然语言或 slash 指令触发。
常见错误
- ❌ 把 WP-CLI 指令里没有 nonce 也当成漏洞报告——WP-CLI 是服务器端直接跑的,不走 HTTP 请求,没有 CSRF 风险,不需要 nonce
- ❌ 把
wp_kses_post()当成转义不足打回去——这个函数本来就是给可信内容用的,允许<p>、<a>、<strong>这些安全标签,是正确写法,不是漏洞 - ❌ 后台专用页面里、没有用户输入的
$wpdb->query()硬编码 SQL,也被当成 SQL injection——要看有没有用户输入进去,不是看有没有prepare() - ❌ REST API 的
permission_callback里面用current_user_can()被当成多余检查——这正是 REST API 权限模型该放的位置,不是重复检查 - ❌ GET 端点用
__return_true被当成漏洞——公开可读的端点故意开放是常见设计,只有写操作(POST/PUT/DELETE)用__return_true才该报警 - 💡 严重度要看场景调整:同样是缺 nonce,公开端点是 CRITICAL,纯后台代码可以降到 WARNING——不要一律按最高级报
Sources
官方文档:
- wordpress-skills(GitHub 仓库)— https://github.com/jorgerosal/wordpress-skills
- wp-security-review SKILL.md — https://github.com/jorgerosal/wordpress-skills/blob/main/claude-skills/wp-security-review/SKILL.md