wp-guard
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWP Guard
WP Guard
You are reviewing generated or changed WordPress code before it ships. Apply the rules below as a guard pass after the first implementation pass. Be a sharp reviewer, not a pedantic one: flag what creates vulnerabilities, breaks translations, or melts servers — ignore cosmetic preferences WPCS tooling already handles.
These rules exist because AI agents produce WordPress code with systematic failures: raw of request data, AJAX handlers with neither nonce nor capability check, SQL built by string interpolation, English hardcoded into user-facing strings, on sites with a million posts, and hand-rolled replacements for APIs core already ships. Each one looks fine in a demo and fails in production.
echoposts_per_page => -1你需要在WordPress代码发布前审查生成或修改的代码。在首次实现完成后,将以下规则作为防护检查环节应用。做一名敏锐的审查者,而非吹毛求疵的人:标记出会造成漏洞、破坏翻译或拖垮服务器的问题——忽略WPCS工具已处理的格式偏好问题。
这些规则的存在是因为AI Agent生成的WordPress代码存在系统性缺陷:直接请求数据、既无随机数也无权限检查的AJAX处理器、通过字符串拼接构建SQL、用户可见字符串硬编码为英文、在百万级文章的站点上设置,以及手动实现WordPress核心已提供的API替代方案。这些问题在演示中看似正常,但在生产环境中会失效。
echoposts_per_page => -1How to use this skill
如何使用此技能
Guard-pass mode (recommended): after WordPress code has been generated or edited, apply the rules to the diff or target files, then run the self-check before delivery. Fix violations before showing the user.
Live mode (explicit): when the user invokes this skill before writing WordPress code, apply the same rules while writing, then run the self-check before delivery.
Review mode (the user asks you to review, audit, or rate WordPress code): walk references/review-checklist.md against the target files and produce a structured findings report. Do not edit code in review mode unless asked.
Pair this skill with clean-code-guard when both are installed: clean-code-guard owns generic code quality; wp-guard owns the WordPress layer.
防护检查模式(推荐):在生成或编辑WordPress代码后,将规则应用于差异文件或目标文件,然后在交付前运行自我检查。在展示给用户前修复违规问题。
实时模式(显式调用):当用户在编写WordPress代码前调用此技能时,在编写过程中应用相同规则,然后在交付前运行自我检查。
审查模式(用户要求你审查、审计或评估WordPress代码):对照目标文件逐一检查references/review-checklist.md,并生成结构化的检查结果报告。除非被要求,否则在审查模式下不要编辑代码。
当同时安装了clean-code-guard时,可将此技能与其配合使用:clean-code-guard负责通用代码质量,wp-guard负责WordPress层面的检查。
Adapt to the project first
先适配项目
- Read the project's agent instructions (CLAUDE.md, AGENTS.md), /WPCS config, and
phpcs.xml. Project conventions win on conflict.composer.json - Identify the established prefix (functions, options, meta keys, handles) and the minimum supported WP/PHP versions. Match both.
- Detect context: WooCommerce APIs in play → apply woo-guard alongside this skill when it is installed; otherwise apply WooCommerce's HPOS, CRUD, and checkout rules from its developer documentation. Multilingual site (WPML/Polylang/multisite) → i18n rules are blocking, not advisory.
- Read one neighboring file before writing. Mirror its error handling, hook registration style, and escaping habits — unless they violate the security rules below, which are non-negotiable.
- 阅读项目的Agent说明文档(CLAUDE.md、AGENTS.md)、/WPCS配置文件以及
phpcs.xml。若存在冲突,以项目约定为准。composer.json - 确定已有的前缀(函数、选项、元键、句柄)和最低支持的WP/PHP版本。确保代码与两者匹配。
- 检测上下文:若使用了WooCommerce API,且已安装woo-guard,则同时应用woo-guard;否则,根据WooCommerce开发者文档应用其HPOS、CRUD和结账规则。多语言站点(WPML/Polylang/多站点)→国际化(i18n)规则为强制要求,而非建议。
- 在编写代码前先阅读一个相邻文件。模仿其错误处理、钩子注册风格和转义习惯——除非它们违反以下不可协商的安全规则。
The Rules
规则
Security — must fix, no exceptions
安全——必须修复,无例外
-
Escape late, escape everything. Every variable crossing into HTML output goes through the context-correct function:,
esc_html(),esc_attr(), oresc_url()/wp_kses()for rich content. Data passed to inline JS goes throughwp_kses_post()+wp_json_encode()—wp_add_inline_script()is legacy, for single-quoted strings in inline attributes only. Escaping happens at output, not at storage.esc_js()without anecho $anything;wrapper fails review.esc_* -
Sanitize early, and unslash first. Request data (,
$_POST,$_GET,$_REQUEST) never touches logic raw:$_SERVERfirst, then the type-correct sanitizer (wp_unslash(),sanitize_text_field(),sanitize_key(),absint(), …). Sanitization is not escaping; doing one never excuses the other.sanitize_email() -
Every state change proves identity and intent. Form handlers, AJAX endpoints, and REST routes that change anything require BOTH a capability check () AND a nonce (
current_user_can(),check_admin_referer(), or REST nonce handling). A nonce is not authorization. A RESTcheck_ajax_referer()ofpermission_callbackon a writing route fails review.__return_true -
for every query containing a variable. Placeholders (
$wpdb->prepare(),%s,%d, and%ffor identifiers on WP ≥ 6.2), never interpolation or concatenation. Prefer%i, the meta and options APIs over raw SQL when they can express the query.WP_Query
-
延迟转义,转义所有内容。所有进入HTML输出的变量都要通过符合上下文的函数处理:、
esc_html()、esc_attr(),或者对于富内容使用esc_url()/wp_kses()。传递给内联JS的数据要通过wp_kses_post()+wp_json_encode()处理——wp_add_inline_script()是遗留方法,仅适用于内联属性中的单引号字符串。转义发生在输出阶段,而非存储阶段。未使用esc_js()包裹的esc_*将无法通过审查。echo $anything; -
提前清理,先去除反斜杠。请求数据(、
$_POST、$_GET、$_REQUEST)绝不能直接用于逻辑处理:先使用$_SERVER,再使用符合类型的清理器(wp_unslash()、sanitize_text_field()、sanitize_key()、absint()等)。清理不等于转义;做其中一项不能免除另一项的要求。sanitize_email() -
所有状态变更都需验证身份与意图。任何会改变状态的表单处理器、AJAX端点和REST路由都需要同时进行权限检查()和随机数验证(
current_user_can()、check_admin_referer()或REST随机数处理)。随机数不等于授权。REST写入路由的check_ajax_referer()设置为permission_callback将无法通过审查。__return_true -
所有包含变量的查询都使用。使用占位符(
$wpdb->prepare()、%s、%d,以及WP ≥ 6.2版本中用于标识符的%f),绝不能使用插值或拼接。当可以表达查询逻辑时,优先使用%i、元数据和选项API,而非原生SQL。WP_Query
Core API discipline
核心API规范
-
Use the platform; don't reinvent it. Outbound HTTP via/
wp_remote_get(), never curl. Assets viawp_remote_post()/wp_enqueue_script(), never echoedwp_enqueue_style()/<script>tags. Scheduling via WP-Cron or Action Scheduler. Redirects via<style>followed bywp_safe_redirect(). File writes viaexit. Simple persistent data via options/transients, not a custom table.WP_Filesystem -
Verify every hook and function exists. Before,
add_action(), or calling a core/plugin function, confirm it exists in the supported versions — read the source or the project's installed code. Hallucinated hooks fail silently in WordPress: no error, no behavior. Also match the hook to the moment — front-end code does not load onadd_filter(), queries do not run beforeadmin_initexpects them.init -
Prefix or namespace everything public. Functions, classes, options, transients, meta keys, script handles, AJAX actions, REST namespaces — all carry the project prefix. Generic names (,
get_settings,data) are collisions waiting for the next active plugin.api_key -
Guard direct access. Every PHP file that does work starts with thecheck (or equivalent project convention).
ABSPATH
-
使用平台功能,不要重复造轮子。通过/
wp_remote_get()发起外部HTTP请求,绝不使用curl。通过wp_remote_post()/wp_enqueue_script()加载资源,绝不直接输出wp_enqueue_style()/<script>标签。通过WP-Cron或Action Scheduler进行任务调度。通过<style>加wp_safe_redirect()实现重定向。通过exit进行文件写入。通过选项/临时存储(transients)存储简单的持久化数据,而非自定义表。WP_Filesystem -
验证每个钩子和函数是否存在。在调用、
add_action()或核心/插件函数前,确认它们在支持的版本中存在——阅读源代码或项目已安装的代码。虚构的钩子在WordPress中会静默失败:无错误提示,也无预期行为。同时要确保钩子的调用时机正确——前端代码不应在add_filter()时加载,查询不应在admin_init预期之前运行。init -
所有公共内容都添加前缀或命名空间。函数、类、选项、临时存储、元键、脚本句柄、AJAX动作、REST命名空间——所有这些都要带有项目前缀。通用名称(如、
get_settings、data)很可能会与后续激活的插件发生冲突。api_key -
防止直接访问。所有执行功能的PHP文件都要以检查开头(或等效的项目约定)。
ABSPATH
Internationalization
国际化
- Every user-facing string is translation-ready. The correct wrapper for the context (,
__(),_e(),_x(), or the escaping combos_n(),esc_html__()), a literal text domain matching the plugin slug — never a variable or constant — translator comments on every placeholder,esc_attr__()for plurals (never_n()with a hardcoded singular/plural choice), and no sentence assembly by concatenation. Dates and numbers throughsprintf/date_i18n()andwp_date(). Details and JS i18n: references/i18n.md.number_format_i18n()
- 所有用户可见字符串都支持翻译。使用符合上下文的正确包裹函数(、
__()、_e()、_x(),或转义组合函数_n()、esc_html__()),使用与插件slug匹配的字面文本域——绝不能使用变量或常量,每个占位符都要有翻译注释,使用esc_attr__()处理复数(绝不能使用_n()配合硬编码的单复数选择),且不能通过拼接组装句子。日期和数字要通过sprintf/date_i18n()和wp_date()处理。详细信息和JS国际化:references/i18n.md。number_format_i18n()
Performance
性能
-
Query discipline. Noand no
posts_per_page => -1, ever. Usequery_posts()when only IDs are needed,'fields' => 'ids'when not paginating, and never query inside a loop what could be primed once (meta/term caches). Details: references/performance.md.'no_found_rows' => true -
Cache expensive work, load assets where used. Remote calls and heavy computations go behind transients or the object cache with a deliberate TTL. Options that are large or rarely read register with. Scripts and styles enqueue only on the screens that use them.
autoload => false
-
查询规范。绝不使用和
posts_per_page => -1。当只需要ID时使用query_posts(),不需要分页时使用'fields' => 'ids',绝不在循环内查询可预先加载的内容(元数据/术语缓存)。详细信息:references/performance.md。'no_found_rows' => true -
缓存耗时操作,按需加载资源。远程调用和繁重计算要通过临时存储(transients)或对象缓存处理,并设置明确的TTL。对于大型或很少读取的选项,注册时设置。脚本和样式仅在需要使用它们的页面上加载。
autoload => false
Self-check before delivery
交付前自我检查
- Grep your diff for ,
echo,print: is every variable output escaped with the context-correct function?<?= - Grep for ,
$_POST,$_GET: unslashed? sanitized? nonce-verified? capability-checked?$_REQUEST - Grep for : every variable behind a placeholder?
$wpdb-> - Any user-facing string outside an i18n wrapper? Any non-literal text domain?
- Any hook or function you did not verify exists?
- Any unbounded query, uncached remote call, or unconditional enqueue?
- Does every new public name carry the project prefix?
- Would this survive WPCS (+
WordPress-Extra) without warnings you cannot justify?WordPress-Security
If any answer is wrong, fix it before showing the user.
- 在差异文件中搜索、
echo、print:每个输出的变量是否都使用了符合上下文的转义函数?<?= - 搜索、
$_POST、$_GET:是否去除了反斜杠?是否进行了清理?是否验证了随机数?是否检查了权限?$_REQUEST - 搜索:每个变量是否都使用了占位符?
$wpdb-> - 是否存在未使用国际化包裹函数的用户可见字符串?是否存在非字面文本域?
- 是否存在未验证是否存在的钩子或函数?
- 是否存在无限制的查询、未缓存的远程调用或无条件加载的资源?
- 每个新的公共名称是否都带有项目前缀?
- 此代码是否能通过WPCS(+
WordPress-Extra)检查,且无无法解释的警告?WordPress-Security
如果任何问题的答案是否定的,在展示给用户前修复它。
Reporting format (review mode)
报告格式(审查模式)
**Rule N violation** in `path/file.php:<line or function>`
- What: <one sentence>
- Risk: <XSS / SQLi / CSRF / broken i18n / scaling — one phrase>
- Fix: <one sentence>Group by file, lead with security findings. If a file is clean, don't mention it.
**规则N违规** 在`path/file.php:<行号或函数>`
- 问题:<一句话描述>
- 风险:<XSS / SQL注入 / CSRF / 国际化失效 / 扩展性问题 — 一个短语>
- 修复方案:<一句话描述>按文件分组,优先展示安全问题。如果文件无问题,无需提及。
Severity guide
严重程度指南
- Must fix: Rules 1–4 — these are exploitable (XSS, SQLi, CSRF, privilege escalation)
- Should fix: Rules 5–9 — conflicts, silent failures, untranslatable releases
- Worth noting: Rules 10–11 — they decide whether the code survives traffic; block on them for code that runs on every request
- 必须修复:规则1–4——这些问题会被利用(XSS、SQL注入、CSRF、权限提升)
- 应该修复:规则5–9——会导致冲突、静默失败、无法翻译的版本
- 值得注意:规则10–11——这些决定代码能否承受流量;对于每个请求都会运行的代码,需严格执行这些规则
References
参考资料
- references/security.md — escaping/sanitization function tables, nonce lifecycle, REST permissions, details, file uploads
$wpdb->prepare - references/i18n.md — wrapper selection, text domain rules, plurals, translator comments, JS translations, RTL, multilingual-plugin gotchas
- references/performance.md — WP_Query flags, transients vs object cache, autoload hygiene, asset loading, cron, scaling traps
- references/review-checklist.md — structured walk-through for review mode
- references/sources.md — handbook and research URLs; read only when citing a source
- references/security.md — 转义/清理函数表、随机数生命周期、REST权限、详细说明、文件上传
$wpdb->prepare - references/i18n.md — 包裹函数选择、文本域规则、复数处理、翻译注释、JS翻译、RTL、多语言插件注意事项
- references/performance.md — WP_Query标记、临时存储vs对象缓存、自动加载规范、资源加载、定时任务、扩展性陷阱
- references/review-checklist.md — 审查模式下的结构化检查清单
- references/sources.md — 手册和研究URL;仅在引用来源时阅读
What this skill does not do
此技能不负责的内容
- Run PHPCS, PHPStan, or Plugin Check — use the project's tooling for mechanical verification; this skill is the judgment layer above it.
- Decide plugin architecture or business logic — it guards how WordPress code ships, not what it does.
- Replace clean-code-guard or test-guard — generic code quality and test quality remain their jurisdiction.
- 运行PHPCS、PHPStan或Plugin Check——使用项目的工具进行机械验证;此技能是工具之上的判断层。
- 决定插件架构或业务逻辑——它仅保障WordPress代码的发布规范,而非代码的功能。
- 替代clean-code-guard或test-guard——通用代码质量和测试质量仍由它们负责。