name: reverse-patch description: A skill that guides the assistant through the systematic reverse-engineering of WordPress extensions security patches.
How to use this skill
When the user asks to analyze a WordPress patch diff, follow this streamlined workflow:
| Step | What to Do | Why |
|---|---|---|
| 1. Snippet Capture (internal) | Scan the diff for all hunks (@@ … @@ blocks). Store each hunk with its file path, line numbers, and the changed code. Do not expose these snippets to the user. |
Keeps a full view of the diff for internal analysis. |
| 2. Relevance Check | For each captured snippet: • Look for security-related cues ( CVE-, sanitize, validate, wp_kses, etc.).• Flag snippets that touch user-supplied data or perform sanitization/validation as relevant; ignore pure refactors. |
Filters out unrelated bug-fixes. |
| 3. Back-Track Until Exploit Path Found | For each relevant snippet: • Identify the function/hook/filter that was modified. • Find all call sites/references of that symbol (or registrations/usages for hooks/filters) using code search tools. • For each call site, recursively walk upward (caller → caller) until reaching a top-level entry point that originates from user input (GET/POST, REST endpoint, AJAX handler, cookie, shortcode, etc.). • While walking the chain, annotate each step with: – Whether the data is tainted (directly from user input). – Any sanitization/validation that occurs (and where). – The final sink where the vulnerability would be exercised (e.g., unsanitized DB query, file include, command execution, SSRF request, etc.). • If dynamic dispatch cannot be resolved, explicitly note the gap and use best-effort heuristics (naming conventions, hook names, WP patterns) plus targeted text search as a fallback. |
Combines "trace caller" + "taint-to-sink" into a single, logical back-tracking process. |
| 4. Produce the Chronological Report | For each relevant snippet, output a concise block: 1. Location – file path & line numbers. 2. Code – the changed code (in a code block). 3. Role – a brief description of its place in the exploit path. 4. Data Flow – how it receives or passes tainted data and where sanitization/validation occurs. After listing all relevant snippets, add a short summary that ties the entire path together and states the final vulnerability sink. Note: When describing call chains, prefer symbol names and function/method signatures over "string match" reasoning. |
Gives the user a focused, actionable understanding of the patch with structurally grounded traces. |
| 5. Ask for Clarification (if needed) | If the diff is ambiguous, missing context, or the user asks for more detail, request: • Full repository or file link. • WordPress version. • Specific issue or CVE number. |
Ensures accurate analysis. |
Important: All code snippets in the assistant's output must be wrapped in Markdown fences for clarity.
Example Output
Chronological Report
wp-includes/rest-api/class-wp-rest-request.php– Lines 112-118Role: Extracts user-supplied$data = $this->get_params(); // Pull raw JSON payload $user_id = $data['user_id']; // <- tainteduser_idfrom the REST request.
Flow: User input →get_params()→$user_id(tainted).wp-includes/rest-api/class-wp-rest-server.php– Lines 345-350Role: Instantiates the request object and dispatches it to the correct endpoint.$request = new WP_REST_Request( $method, $route, $args ); $response = $this->dispatch( $request );
Flow: Receives$requestwith tainted$user_id.wp-json/wp/v2/users/(?P<id>\d+)(REST route) – Lines 78-84Role: Maps the URL to theregister_rest_route( 'wp/v2', '/users/(?P<id>\d+)', array( 'methods' => 'GET', 'callback' => 'wp_rest_get_user', ) );wp_rest_get_usercallback.
Flow: User'suser_idpassed as route parameter to callback.wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php– Lines 512-520Role: Retrieves the user from the database using the unsanitized$user = get_user_by( 'id', $user_id ); // <- missing sanitizationuser_id.
Sink: Potential for integer-based SQL injection if$user_idis not validated.Summary – The patch added a sanitization step in step 4 (e.g.,
absint( $user_id )) to ensure the ID is a valid integer before querying the database. This closes the integer-based injection path that was the core vulnerability.
Key Takeaway
The combined "Back-Track Until Exploit Path Found" step ensures that you trace the exact chain from user input to the vulnerable code, giving you a clear picture of why the patch was necessary and how you can build prevention measures around it.