Browse 158 rules, 25 knowledge articles, and 25 prompt templates across security, performance, architecture, and quality.
158 rules
WordPress provides context-specific escaping functions. Using the wrong one — or none — enables XSS. Match esc_html, esc_attr, esc_url, wp_kses to the output context. [CWE-79 · A07:2021]
Passing user input directly into SQL queries via $wpdb enables SQL injection. Always use $wpdb->prepare() with typed placeholders (%d, %s, %f, %i). [CWE-89 · A03:2021]
WordPress capabilities (current_user_can) are the authorization layer. Missing checks in REST endpoints, admin handlers, and AJAX allow subscribers to perform admin actions. [CWE-862 · A01:2021]
User input in include/require or file read/write paths allows attackers to read wp-config.php, delete files, or execute arbitrary PHP via ../ sequences. [CWE-22 · A01:2021]
PHP's unserialize() instantiates arbitrary classes and triggers magic methods. Deserialization of user input enables remote code execution via gadget chains. [CWE-502 · A08:2021]
Direct move_uploaded_file() with only client-supplied MIME checks enables shell upload. Use wp_handle_upload() which validates both extension and file content. [CWE-434 · A04:2021]
PHP files without an ABSPATH guard can be accessed directly via URL, leaking paths, triggering errors, or executing partial logic without WordPress security context. [CWE-425 · A05:2021]
WordPress nonces prevent CSRF attacks. Every form submission, AJAX call, and admin action that modifies data must verify a nonce before processing. [CWE-352 · A01:2021]
WordPress AJAX handlers are public endpoints. wp_ajax_ fires for any logged-in user regardless of role. Always verify nonces and capabilities inside each handler. [CWE-862 · A01:2021]
Returning false on failure hides what went wrong. WP_Error provides structured error codes, messages, and data — matching WordPress core's error handling pattern.
Raw $_GET/$_POST/$_REQUEST data can contain anything. WordPress provides type-specific sanitization functions — use the right one for each data type before storage or use. [CWE-20 · A03:2021]
Hardcoded English strings prevent localization. Use __(), _e(), and esc_html__() with a text domain. Always escape translated output — translators can inject HTML.
External API calls, complex calculations, and aggregation queries should use set_transient/get_transient to avoid repeating expensive work on every page load.
Direct $wpdb queries and query_posts() in template files create redundant queries, bypass caching, and mix data logic with presentation.
Inline script tags bypass WordPress dependency management and load on every page. Use wp_enqueue_script with conditions to load assets only where needed.
wp_cache_get/set with a persistent backend (Redis/Memcached) eliminates redundant database queries across requests. Without it, identical queries run on every page load.
Calling get_post_meta() inside loops without cache priming generates one database query per post. Use update_post_meta_cache or meta_query to batch lookups.
All autoloaded options are loaded into memory on every page request. Large serialized arrays in autoloaded options waste memory and slow every page.
Direct SQL, curl, file_put_contents, and mail() bypass WordPress caching, hooks, security filters, and host compatibility. Use WP_Query, wp_remote_get, WP_Filesystem, and wp_mail.
Registering CPTs on plugins_loaded, enqueueing scripts on init, or running admin-only code on every request wastes resources and causes subtle bugs.
Hardcoded URLs and filesystem paths break across environments (local/staging/prod), subdirectory installs, multisite, and custom wp-content directories.
String interpolation in .rpc() calls or custom PostgreSQL functions allows attackers to inject arbitrary SQL. Always use parameterized queries. [CWE-89 · A03:2021]
createServiceRoleClient() bypasses ALL RLS policies. Using it in request handlers lets any authenticated user access or modify all data. [CWE-269 · A04:2021]
Logging OAuth tokens, API keys, passwords, or PII exposes secrets in log aggregation services and crash reporters. Use scoped loggers with sanitization. [CWE-532 · A09:2021]
BeforeMerge scans your pull requests against these rules automatically. Get actionable feedback before code ships to production.