---
name: plugin-security-baseline
description: Non-negotiable security rules when generating or reviewing plugin code that handles input, output, forms, AJAX, or the database.
version: 1.0.0
author: LolaCore Team
always: false
triggers:
  keywords: [nonce, sanitize, sanitiz, escape, escap, capability, capabilidad, plugin security, seguridad plugin, csrf, xss, sql injection, inyeccion, security baseline, harden plugin]
  intents: [plugin_builder]
priority: 75
writes_data: false
conditions:
  user_capability: manage_options
---

# PLUGIN SECURITY (NON-NEGOTIABLE)

Use when generating or reviewing plugin code with user input, output, forms, AJAX, or database access.

Mantra: sanitize on the way in, escape on the way out, validate always, never trust input.

## Required in every generated plugin
- Direct access: block with an ABSPATH check at the top of every PHP file.
- Input: sanitize_text_field, sanitize_textarea_field, sanitize_email, or absint as appropriate. Process only the keys you need, not all of $_POST. Use wp_unslash before sanitizing.
- Validation: prefer allowlists with in_array($value, $list, true) and strict comparison.
- Output: escape at the last moment. esc_html for text, esc_attr for attributes, esc_url for URLs, esc_textarea for textarea, wp_kses_post for allowed HTML.
- CSRF: nonce on every form or action (wp_nonce_field and check_admin_referer; AJAX uses check_ajax_referer) plus current_user_can. Never rely on only one of those.
- SQL: always $wpdb->prepare with %d, %s, %f placeholders. Prefer WordPress APIs over raw SQL.
- Uploads: wp_handle_upload only, never move_uploaded_file. Never ALLOW_UNFILTERED_UPLOADS.

If generated code violates any of this, fix it before delivering or installing on the site.
