WordPress Engineering · 2 min read

WordPress Security for Custom Themes and Plugins

A developer-focused security guide covering capabilities, nonces, validation, escaping, secrets, updates and operational hardening.

Modular WordPress code core protected by capability, input validation, update and secret-management shields

Secure hosting and maintained core software are necessary, but custom code defines many of a WordPress site’s most important trust boundaries. Themes and plugins process editor input, expose AJAX or REST endpoints, query data and call external services. Each boundary needs explicit authorization and context-aware handling.

Authorization is more than authentication

Being logged in does not mean a user may perform an action. Check a specific capability for every privileged screen, endpoint and state change. For object-level operations, verify access to the particular post, order or custom record. Do not rely on a hidden button or an admin URL as protection.

Use nonces for intent, capabilities for permission

A nonce helps protect a request from cross-site submission, but it does not grant authority. Verify both. REST routes require a permission callback that denies by default. Public endpoints need rate limits and validation appropriate to the operation, especially when they trigger email, search or remote API calls.

Validate input and escape at output

Sanitize and validate values according to their domain: identifiers, URLs, email addresses, enums or structured arrays. When rendering, escape for HTML text, attributes, URLs or JavaScript as appropriate. Prepared database statements protect variable values, while table or column names must come from controlled allowlists.

  • Never store API credentials in theme files or the repository
  • Verify upload type, size and destination instead of trusting extensions
  • Protect webhook endpoints with signatures and replay controls
  • Keep dependencies, WordPress core and PHP on supported versions
  • Log privileged actions without logging passwords, tokens or sensitive payloads

Minimize the blast radius

Use least-privilege database and service credentials. Disable editing of production files through the admin interface. Restrict admin access, add multi-factor authentication and separate staging from production data. Backups need tested restoration; an unverified backup is only an assumption.

Review custom surfaces repeatedly

Inventory REST routes, AJAX handlers, shortcodes, upload flows, scheduled jobs and external callbacks. Test low-privilege users and unauthenticated requests. Automated dependency scanning helps, but logic flaws in capabilities and object access require application-aware review.

A secure custom build is not finished at launch. Clear ownership, fast patching, monitored errors and rehearsed recovery keep the site dependable as content, integrations and attack patterns change.