orbit-ajax-fuzzerlisted
Install: claude install-skill adityaarsharma/orbit
# 🪐 orbit-ajax-fuzzer — admin-ajax.php fuzzing
REST has a fuzzer. Legacy AJAX (`admin-ajax.php`) needs one too — it's a different attack surface, often less hardened.
---
## Quick start
```bash
PLUGIN_SLUG=my-plugin \
WP_TEST_URL=http://localhost:8881 \
bash ~/Claude/orbit/scripts/ajax-fuzz.sh
```
Output: `reports/ajax-fuzz-<timestamp>.md`.
---
## How it works
1. Scan plugin source for `add_action('wp_ajax_*', ...)` and `add_action('wp_ajax_nopriv_*', ...)`
2. For each:
- Detect the handler function
- Check for nonce verification (`check_ajax_referer`, `wp_verify_nonce`)
- Check for capability check (`current_user_can`)
- Detect what params it accepts
3. Send fuzz requests to `/wp-admin/admin-ajax.php?action=<action>`:
- **Logged out** (for `nopriv` actions only)
- **Logged in but no nonce** — must reject if action has `check_ajax_referer`
- **Logged in with wrong nonce** — must reject
- **Logged in with correct nonce, no capability** — must reject if `current_user_can` is required
- **Type juggling, injection, oversized body** — same suite as REST fuzzer
4. Record responses, flag misses
---
## What it catches
### Missing nonce check
```php
// ❌ Vulnerable — no nonce, accepts any logged-in user
add_action( 'wp_ajax_my_save', function() {
update_option( 'my_setting', $_POST['value'] );
wp_send_json_success();
} );
// ✅
add_action( 'wp_ajax_my_save', function() {
check_ajax_referer( 'my_save_nonce', 'nonce' );
if ( ! current_use