Implement WooCommerce security — nonces, capabilities, input sanitization, output escaping, data validation, PCI compliance considerations, and WordPress security best practices. Use when hardening a WooCommerce store or reviewing security posture.
Scanned 9/7/2026
Install to Claude Code
npx -y skills add OrcaQubits/agentic-commerce-skills-plugins --skill woo-security --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Woo Security?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/orcaqubits-woo-security-agentic-commerce-skills-plugin)More formats (shields.io, HTML) on the badges page.
---
name: woo-security
description: Implement WooCommerce security — nonces, capabilities, input sanitization, output escaping, data validation, PCI compliance considerations, and WordPress security best practices. Use when hardening a WooCommerce store or reviewing security posture.
allowed-tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch
---
# WooCommerce Security
## Before writing code
**Fetch live docs**:
1. Web-search `site:developer.wordpress.org plugins security` for WordPress security handbook
2. Web-search `site:developer.woocommerce.com security best practices` for WooCommerce security
3. Web-search `wordpress security hardening latest` for current hardening guidance
## Nonces (CSRF Protection)
### How Nonces Work
WordPress nonces prevent Cross-Site Request Forgery:
- Generate: `wp_create_nonce( 'my_action' )` or `wp_nonce_field( 'my_action', 'my_nonce' )` (for forms)
- Verify: `wp_verify_nonce( $_POST['my_nonce'], 'my_action' )` or `check_admin_referer( 'my_action', 'my_nonce' )`
- Valid for 24 hours (two 12-hour ticks)
### AJAX Nonces
- Generate: `wp_create_nonce( 'my_ajax_action' )`
- Pass to JS via `wp_localize_script()`: `['nonce' => wp_create_nonce('my_ajax_action')]`
- Verify in handler: `check_ajax_referer( 'my_ajax_action', 'nonce' )`
### REST API Nonces
- Cookie auth uses `X-WP-Nonce` header with `wp_create_nonce( 'wp_rest' )`
- API key auth doesn't need nonces (keys provide authentication)
## Capabilities (Authorization)
### WordPress Capability System
Always check capabilities before performing actions:
- `current_user_can( 'manage_woocommerce' )` — WooCommerce admin
- `current_user_can( 'edit_shop_orders' )` — order management
- `current_user_can( 'edit_products' )` — product management
- `current_user_can( 'view_woocommerce_reports' )` — view reports
### WooCommerce Capabilities
| Capability | Access |
|------------|--------|
| `manage_woocommerce` | Full WooCommerce admin |
| `edit_products` | Create/edit products |
| `edit_shop_orders` | Manage orders |
| `view_woocommerce_reports` | View analytics/reports |
| `edit_shop_coupons` | Manage coupons |
### Custom Capabilities
Register custom capabilities via `add_cap()` on role objects during plugin activation.
## Input Sanitization
### Sanitization Functions
Always sanitize data before using or storing it:
| Function | Use For |
|----------|---------|
| `sanitize_text_field()` | Single-line text input |
| `sanitize_textarea_field()` | Multi-line text |
| `sanitize_email()` | Email addresses |
| `sanitize_url()` | URLs |
| `absint()` | Positive integers |
| `intval()` | Integers (any sign) |
| `floatval()` | Float numbers |
| `wp_kses()` | HTML with allowed tags |
| `wp_kses_post()` | HTML safe for post content |
| `wc_clean()` | WooCommerce string/array sanitizer |
| `wc_sanitize_textarea()` | WooCommerce textarea sanitizer |
### Array Sanitization
`wc_clean()` recursively sanitizes arrays — use for multi-value inputs.
### File Upload Validation
- Validate MIME type with `wp_check_filetype()`
- Use `wp_handle_upload()` for proper file upload processing
- Never trust file extensions — validate content
## Output Escaping
### Escaping Functions
Always escape data on output:
| Function | Context |
|----------|---------|
| `esc_html()` | Inside HTML tags |
| `esc_attr()` | HTML attribute values |
| `esc_url()` | URLs (href, src) |
| `esc_js()` | Inline JavaScript |
| `esc_textarea()` | Inside textarea elements |
| `wp_kses()` | HTML with specific allowed tags |
| `wp_kses_post()` | HTML safe for post content |
### Translation + Escaping
Combine translation with escaping:
- `esc_html__()` / `esc_html_e()` — escaped translated strings
- `esc_attr__()` / `esc_attr_e()` — escaped for attributes
- `wp_kses( sprintf(...), $allowed_html )` — formatted HTML
### The Rule
**Sanitize early (on input), escape late (on output).** Never trust any data from users, databases, or external APIs.
## Data Validation
### Validation Patterns
- Validate data type, format, and range before processing
- Use `is_email()`, `wp_http_validate_url()`, WordPress validators
- WooCommerce validators: `wc_format_decimal()`, `wc_is_valid_url()`
- Return errors via `WP_Error` or `wc_add_notice( $msg, 'error' )`
## SQL Injection Prevention
### Prepared Statements
Always use `$wpdb->prepare()` for custom queries:
- `$wpdb->prepare( "SELECT * FROM {$wpdb->prefix}my_table WHERE id = %d", $id )`
- Placeholders: `%d` (integer), `%s` (string), `%f` (float)
- Never concatenate user input into SQL strings
### Use CRUD/APIs Instead
Prefer WooCommerce CRUD and WordPress APIs over raw SQL:
- `wc_get_orders()`, `wc_get_products()` — safe query builders
- `$order->get_meta()`, `$product->get_price()` — safe data access
## PCI Compliance Considerations
- **Never** store raw credit card numbers
- Use tokenized payment methods (Stripe, Braintree SDKs handle card data client-side)
- Serve checkout over HTTPS
- Keep WordPress, WooCommerce, and all plugins up to date
- Use payment gateways that are PCI DSS compliant
## Additional Hardening
- Set `DISALLOW_FILE_EDIT` in wp-config.php
- Limit login attempts (plugin or `.htaccess`)
- Use strong admin passwords and enforce password policies
- Enable two-factor authentication for admin users
- Keep all software updated (WordPress, WooCommerce, plugins, PHP)
- Use HTTPS everywhere
- Set secure cookie flags
- Restrict REST API access where appropriate (`rest_authentication_errors` filter)
- Disable XML-RPC if not needed: `add_filter( 'xmlrpc_enabled', '__return_false' )`
## Best Practices
- Check nonces on every form submission and AJAX request
- Check capabilities before every privileged operation
- Sanitize ALL input — even from trusted sources
- Escape ALL output — even data from the database
- Use `$wpdb->prepare()` for any custom SQL
- Never store sensitive data in plain text
- Use WordPress APIs instead of raw PHP functions for security-sensitive operations
- Run security audits with WPScan or similar tools
Fetch the WordPress Security handbook and WooCommerce security documentation for exact function signatures, capability mappings, and current best practices before implementing.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!