[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f8mRVP9HK6rj0b5XnQ51ps-7kluqc4h9HLVr-KrgogZ0":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":9,"severity":11,"cvss_score":12,"cvss_vector":13,"vuln_type":14,"published_date":15,"updated_date":16,"references":17,"days_to_patch":9,"patch_diff_files":19,"patch_trac_url":9,"research_status":20,"research_verified":21,"research_rounds_completed":22,"research_plan":23,"research_summary":24,"research_vulnerable_code":25,"research_fix_diff":26,"research_exploit_outline":27,"research_model_used":28,"research_started_at":29,"research_completed_at":30,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":21,"poc_model_used":9,"poc_verification_depth":9,"source_links":31},"CVE-2026-4002","petjeaf-cross-site-request-forgery-to-account-deletion-via-petjeafdisconnect-ajax-action","Petje.af \u003C= 2.1.8 - Cross-Site Request Forgery to Account Deletion via 'petjeaf_disconnect' AJAX Action","The Petje.af plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to and including 2.1.8. This is due to missing nonce validation in the ajax_revoke_token() function which handles the 'petjeaf_disconnect' AJAX action. The function performs destructive operations including revoking OAuth2 tokens, deleting user meta, and deleting WordPress user accounts (for users with the 'petjeaf_member' role) without verifying the request originated from a legitimate source. This makes it possible for unauthenticated attackers to force authenticated users to delete their Petje.af member user accounts via a forged request granted the victim clicks on a link or visits a malicious site.","petje-af",null,"\u003C=2.1.8","medium",4.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:R\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Cross-Site Request Forgery (CSRF)","2026-04-14 19:46:31","2026-04-15 08:28:14",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F28a071ac-37ee-4fb9-b8c6-0a782ee673b4?source=api-prod",[],"researched",false,3,"# Exploitation Research Plan: CVE-2026-4002 Petje.af CSRF to Account Deletion\n\n## 1. Vulnerability Summary\nThe **Petje.af** plugin (versions \u003C= 2.1.8) is vulnerable to a Cross-Site Request Forgery (CSRF) attack due to the absence of nonce validation in the `ajax_revoke_token()` function. This function is hooked to the `petjeaf_disconnect` AJAX action. \n\nThe function performs several destructive operations, including revoking OAuth2 tokens, removing user metadata, and—most critically—deleting the WordPress user account if the authenticated user has the `petjeaf_member` role. Because there is no check (like `check_ajax_referer`) to ensure the request is intentional and originated from the plugin's interface, an attacker can trick an authenticated user into visiting a malicious page that triggers this action, leading to unauthorized account deletion.\n\n## 2. Attack Vector Analysis\n- **Endpoint**: `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **AJAX Action**: `petjeaf_disconnect`\n- **HTTP Method**: POST (or GET, as `admin-ajax.php` processes both, though POST is the standard for state-changing actions).\n- **Vulnerable Parameter**: `action=petjeaf_disconnect`\n- **Authentication Level**: Required (Victim must be authenticated with the `petjeaf_member` role).\n- **Preconditions**:\n    1. The victim must be logged in to the WordPress site.\n    2. The victim must have the WordPress role `petjeaf_member`.\n    3. The victim must be tricked into executing a cross-origin request (e.g., clicking a link or visiting an attacker-controlled site).\n\n## 3. Code Flow (Inferred)\n1. **Entry Point**: A user's browser sends a request to `admin-ajax.php?action=petjeaf_disconnect`.\n2. **Hook Registration**: The plugin registers the action via:\n   `add_action( 'wp_ajax_petjeaf_disconnect', [ $this, 'ajax_revoke_token' ] );`\n3. **Vulnerable Function**: The `ajax_revoke_token()` method in the plugin's AJAX handler class is executed.\n4. **Missing Check**: The function fails to call `check_ajax_referer( 'petjeaf_disconnect', ... )` or `wp_verify_nonce()`.\n5. **Privileged Logic**:\n   - The function identifies the current user via `get_current_user_id()`.\n   - It revokes the OAuth2 token associated with the user.\n   - It checks if the current user has the `petjeaf_member` role using `current_user_can( 'petjeaf_member' )` or by checking the `$user->roles` array.\n   - If the role matches, it calls `wp_delete_user( $user_id )`.\n6. **Sink**: The WordPress core `wp_delete_user()` function is invoked, permanently removing the user from the database.\n\n## 4. Nonce Acquisition Strategy\n**No nonce is required.**\nThe vulnerability description explicitly states that the issue is \"missing nonce validation.\" Therefore, the `ajax_revoke_token()` function does not verify a security token. An attacker does not need to bypass or obtain any nonce to exploit this vulnerability.\n\n## 5. Exploitation Strategy\nThe goal is to demonstrate that an authenticated `petjeaf_member` can have their account deleted via a simple CSRF request.\n\n### Step-by-Step Plan:\n1. **Session Preparation**: Use the `http_request` tool to authenticate as a user with the `petjeaf_member` role (created during setup).\n2. **Execution**: Send a POST request to the AJAX endpoint while the session is active.\n3. **Payload**:\n   - **URL**: `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n   - **Method**: `POST`\n   - **Headers**: `Content-Type: application\u002Fx-www-form-urlencoded`\n   - **Body**: `action=petjeaf_disconnect`\n\n### Playwright (http_request) Payload:\n```javascript\n{\n  \"url\": \"http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php\",\n  \"method\": \"POST\",\n  \"headers\": {\n    \"Content-Type\": \"application\u002Fx-www-form-urlencoded\"\n  },\n  \"data\": \"action=petjeaf_disconnect\"\n}\n```\n\n## 6. Test Data Setup\nTo effectively test the vulnerability, the following environment must be prepared via WP-CLI:\n\n1. **Ensure the Role Exists**: Some plugins only create roles when certain settings are configured. Ensure the role exists:\n   `wp role create petjeaf_member \"Petje.af Member\"`\n2. **Create Victim User**:\n   `wp user create victim victim@example.com --role=petjeaf_member --user_pass=password123`\n3. **Ensure Plugin is Active**:\n   `wp plugin activate petje-af`\n\n## 7. Expected Results\n- **HTTP Response**: The server should return a successful response (likely a JSON object `{\"success\":true}` or a `200 OK` with a `1` or `0` body, which is common for WordPress AJAX).\n- **Database Change**: The user account associated with the `victim` username should be removed from the `wp_users` table.\n- **Session Termination**: Subsequent requests using the victim's cookies should fail as the user no longer exists.\n\n## 8. Verification Steps\nAfter executing the exploit via `http_request`, verify the deletion using WP-CLI:\n\n1. **Check User List**:\n   `wp user list --field=user_login`\n   *Expected result: `victim` should NOT be in the list.*\n2. **Verify Deletion via ID**:\n   `wp user get victim`\n   *Expected result: Error: \"Invalid user ID, email or login: 'victim'\"*\n3. **Check User Meta** (Alternative if account wasn't fully deleted but meta was):\n   `wp usermeta list victim`\n\n## 9. Alternative Approaches\nIf the POST request is blocked or requires specific headers:\n1. **GET Request**: Try triggering the action via GET: \n   `GET \u002Fwp-admin\u002Fadmin-ajax.php?action=petjeaf_disconnect`\n2. **Refined Role Check**: If the plugin checks for specific user meta instead of just the role, manually add that meta before testing:\n   `wp usermeta add victim petjeaf_token \"test_token_value\"`\n3. **Referer Header**: Some security plugins might block requests with missing Referers. If the exploit fails in the test environment, ensure the `Referer` header is set to the site's own domain to simulate a standard cross-site bypass (though the core vulnerability doesn't check nonces).","The Petje.af plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) due to a lack of nonce validation in the `ajax_revoke_token()` function. An attacker can trick an authenticated user with the 'petjeaf_member' role into clicking a malicious link, resulting in the unauthorized deletion of their WordPress account and revocation of OAuth2 tokens.","\u002F\u002F Inferred from research plan and plugin functionality\n\u002F\u002F Likely located in an AJAX handler class within the plugin\n\npublic function ajax_revoke_token() {\n    $user_id = get_current_user_id();\n    if ( ! $user_id ) {\n        wp_send_json_error( 'User not logged in' );\n    }\n\n    \u002F\u002F Destructive logic: revokes tokens and removes user meta\n    \u002F\u002F ... \n\n    $user = get_userdata( $user_id );\n    if ( in_array( 'petjeaf_member', (array) $user->roles ) ) {\n        require_once( ABSPATH . 'wp-admin\u002Fincludes\u002Fuser.php' );\n        \u002F\u002F The critical sink: no nonce or intent verification before deletion\n        wp_delete_user( $user_id );\n    }\n\n    wp_send_json_success();\n}","--- a\u002Fincludes\u002Fclass-petjeaf-ajax.php\n+++ b\u002Fincludes\u002Fclass-petjeaf-ajax.php\n@@ -10,6 +10,7 @@\n     public function ajax_revoke_token() {\n+        check_ajax_referer( 'petjeaf_disconnect', 'security' );\n         $user_id = get_current_user_id();\n         if ( ! $user_id ) {\n             wp_send_json_error( 'User not logged in' );\n         }","The exploit targets the AJAX endpoint `\u002Fwp-admin\u002Fadmin-ajax.php` using the `petjeaf_disconnect` action. An attacker crafts a malicious webpage containing a form or script that triggers a POST request to this endpoint with the payload `action=petjeaf_disconnect`. Because the `ajax_revoke_token()` function does not perform any nonce validation (e.g., via `check_ajax_referer`), the WordPress core will process the request using the victim's session cookies. If the victim is authenticated and has the `petjeaf_member` role, the server-side logic will proceed to invoke `wp_delete_user()`, effectively deleting the victim's account without their consent or knowledge.","gemini-3-flash-preview","2026-04-16 15:40:37","2026-04-16 15:41:00",{"type":32,"vulnerable_version":9,"fixed_version":9,"vulnerable_browse":9,"vulnerable_zip":9,"fixed_browse":9,"fixed_zip":9,"all_tags":33},"plugin","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpetje-af\u002Ftags"]