← Back to the catalog

Skill · Version 1.0.0

WordPress input and access protection

Checks how WordPress forms, AJAX handlers and REST routes accept data and enforce permissions. Separates request-intent checks from actual access rights and escapes output for its display context.

wordpress-security

See how it helps

When is it useful?

Use it when a plugin or theme accepts input, handles uploads or changes protected records.

What does it help you do?

  • Validates input and checks both request tokens and the required capability.
  • Escapes displayed values and uses parameterized database queries.
  • Restricts uploaded file types, sizes and permitted filesystem paths.

Try asking this

Review a plugin endpoint that lets editors update an event and upload its cover. An expired request token, a user without editing rights and an oversized executable must all be rejected. A valid editor should still save a permitted image, and event titles must display as text.

Detailed documentation

Read the skill’s original instructions, examples and checks in their authored language.

Details…Show less

WordPress Security

Escape output, late

  • Escape at the point of output for its context: esc_html for text, esc_attr for attributes, esc_url for links, esc_js for inline JS strings, esc_textarea for textareas.
  • Allowed HTML: wp_kses_post for post-like content, wp_kses with an explicit allowlist otherwise.
  • Use escaping i18n functions (esc_html__, esc_attr_e). Escape data you think is safe too: options, post meta, API responses.
  • Data for JS: wp_json_encode, wp_add_inline_script or wp_localize_script.

Sanitize input, early

  • Unslash, then sanitize superglobals: sanitize_text_field( wp_unslash( $_POST['x'] ?? '' ) ).
  • Use the specific sanitizer: absint, sanitize_email, sanitize_key, sanitize_title, sanitize_textarea_field, sanitize_file_name, esc_url_raw.
  • Validate enums, sort keys and statuses against an allowlist with in_array( $v, $allowed, true ).
  • register_setting with a sanitize_callback.

Nonces and capabilities on every handler

  • Every form, admin-post action, AJAX call and state-changing link carries a nonce (wp_nonce_field, wp_create_nonce) verified with check_admin_referer, check_ajax_referer or wp_verify_nonce.
  • A nonce proves intent, not permission: also check current_user_can() with the specific capability (edit_post with the ID, manage_options), never is_admin() or role names.
  • wp_ajax_nopriv_ handlers are public: treat their input as hostile and perform no privileged action there.
  • REST: every register_rest_route has a permission_callback checking capabilities; __return_true only for truly public read-only data. Validate args with schema callbacks.

Database

  • $wpdb->prepare() for every query containing variables, with %d, %s, %f (and %i for identifiers on WP 6.2+). Never interpolate.
  • $wpdb->esc_like() before adding LIKE wildcards.
  • Prefer WP APIs (WP_Query, get_posts, update_post_meta) and $wpdb->insert / update / delete with format arrays.

Files and redirects

  • Uploads through wp_handle_upload or media_handle_upload with an explicit mimes allowlist, wp_check_filetype_and_ext and a size cap. No unsanitized SVG.
  • Never include or read paths built from user input; check with validate_file and realpath against the allowed directory.
  • Redirect with wp_safe_redirect() followed by exit.

Configuration and secrets

  • No API keys, passwords or license keys in theme or plugin code; read them from wp-config.php constants or options, and never echo them into admin HTML.
  • Recommend DISALLOW_FILE_EDIT true in wp-config.php, WP_DEBUG_DISPLAY off in production, and no PHP execution in uploads.
  • Guard direct access at the top of PHP files: if ( ! defined( 'ABSPATH' ) ) { exit; }.

Dependencies

  • Keep plugins and themes updated; flag abandoned or vulnerable ones you encounter.
  • Bundle libraries through the repo's Composer or npm setup, at maintained versions, prefixed if they may clash.

Before you finish

  • All output escaped for its context; all input unslashed and sanitized.
  • Every form, AJAX and admin handler checks a nonce and a capability.
  • Every REST route has a real permission_callback.
  • All variable SQL goes through $wpdb->prepare.
  • Uploads restricted by type and size; no user-controlled paths.
  • No secrets in plugin or theme files; ABSPATH guards present.

Included files 1

  • SKILL.md

About this skill package

wordpress-security

wordpress-security: Make access rules explicit and enforce them on the server, with permission scenarios and audit evidence.

Details…Show less

wordpress-security

wordpress-security: Make access rules explicit and enforce them on the server, with permission scenarios and audit evidence.

Includes the complete skill and its supporting files (1 files). The exact authored scope is preserved below.

Original skill description (source language)

Use when WordPress PHP handles a form, admin page, AJAX, REST API endpoint, shortcode or user input and needs escape output, sanitize input, nonce and capability checks, current_user_can, $wpdb prepare, file upload limits or plugin and theme hardening.

Install the skill, review its source and trust settings, then enable it for the relevant project or agent.

Requirements

  • Orqestria installed on your computer.