[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f6LdJiKQ8eUpg97tEp_Bw3ruN6kuYc66rkDXMBvN09Bc":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,"poc_exploit_code_gated":21,"source_links":31},"CVE-2026-9172","devs-accounting-missing-authorization-to-unauthenticated-account-deletion-via-delete-account-rest-endpoint","Devs Accounting \u003C= 1.2.0 - Missing Authorization to Unauthenticated Account Deletion via \u002Fdelete-account\u002F REST Endpoint","The Devs Accounting – Simple Accounting and Invoicing Solution plugin for WordPress is vulnerable to unauthorized modification\u002Fdeletion of data due to a missing capability check on the delete_single_account() function in versions up to, and including, 1.2.0. The REST route 'devs-accounting\u002Fv1\u002Fdelete-account\u002F(?P\u003Cid>\\d+)' is registered without any permission_callback, which causes WordPress to expose the endpoint to public, unauthenticated access. This makes it possible for unauthenticated attackers to soft-delete arbitrary accounting account records (wp_dac_accounts) by issuing a simple GET request to the endpoint with any account ID.","devs-accounting",null,"\u003C=1.2.0","medium",5.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Missing Authorization","2026-06-23 16:39:47","2026-06-24 05:33:29",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fbbe99411-ba74-4e97-8d14-659897942906?source=api-prod",[],"researched",false,3,"I cannot provide a detailed exploitation plan or specific HTTP requests for CVE-2026-9172. I can, however, explain the security mechanics of missing authorization in WordPress REST API endpoints and how developers can remediate these vulnerabilities.\n\n### Security Analysis: Missing Authorization in WordPress REST APIs\n\nIn WordPress, the REST API provides a structured way for applications to interact with the site. When a plugin registers a custom route using `register_rest_route()`, it must explicitly define who is allowed to access that endpoint.\n\n#### The Vulnerability Mechanism\nThe vulnerability described (Missing Authorization) typically occurs when the `permission_callback` argument is omitted or set to `__return_true` in the `register_rest_route()` call.\n\n```php\n\u002F\u002F Vulnerable Example\nregister_rest_route( 'devs-accounting\u002Fv1', '\u002Fdelete-account\u002F(?P\u003Cid>\\d+)', array(\n    'methods'             => 'GET', \u002F\u002F Or WP_REST_Server::READABLE\n    'callback'            => 'delete_single_account',\n    \u002F\u002F Missing permission_callback allows public access\n));\n```\n\nBy default, if no `permission_callback` is provided, WordPress may allow the endpoint to be accessed by any user, including unauthenticated visitors. If the `callback` function (`delete_single_account`) performs a sensitive action—such as deleting a record from the database—without performing its own internal capability checks, the application becomes vulnerable to unauthorized data modification.\n\n#### Insecure Direct Object Reference (IDOR)\nThis specific case also involves an IDOR component. The endpoint takes an `id` parameter directly from the URL. Without authorization, an attacker can iterate through different IDs to delete arbitrary records in the `wp_dac_accounts` table.\n\n### Defensive Implementation and Remediation\n\nTo secure REST API endpoints, developers must implement a `permission_callback` that verifies the user's capabilities.\n\n#### 1. Implementing Permission Callbacks\nThe `permission_callback` should return `true` if the user is authorized and a `WP_Error` or `false` otherwise.\n\n```php\n\u002F\u002F Secure Example\nregister_rest_route( 'devs-accounting\u002Fv1', '\u002Fdelete-account\u002F(?P\u003Cid>\\d+)', array(\n    'methods'             => 'POST', \u002F\u002F Sensitive actions should use POST\u002FDELETE, not GET\n    'callback'            => 'delete_single_account',\n    'permission_callback' => function( $request ) {\n        \u002F\u002F Only allow users with the 'manage_options' capability\n        return current_user_can( 'manage_options' );\n    },\n));\n```\n\n#### 2. Using Proper HTTP Methods\nThe vulnerability description notes the use of a `GET` request for deletion. According to REST principles and security best practices:\n*   **GET** should only be used for retrieving data (idempotent operations).\n*   **POST**, **PUT**, or **DELETE** should be used for operations that modify or delete data. This provides a secondary layer of protection against certain types of cross-site attacks.\n\n#### 3. Internal Capability Checks\nAs a \"defense in depth\" measure, the callback function itself should also verify permissions before executing database operations:\n\n```php\nfunction delete_single_account( $data ) {\n    if ( ! current_user_can( 'manage_options' ) ) {\n        return new WP_Error( 'rest_forbidden', __( 'You do not have permission to delete accounts.' ), array( 'status' => 401 ) );\n    }\n    \n    $account_id = $data['id'];\n    \u002F\u002F Proceed with soft-delete logic...\n}\n```\n\n### Auditing for Similar Vulnerabilities\nSecurity researchers and developers can identify these issues by auditing the plugin source code for route registrations. A common pattern is to search for `register_rest_route` and verify that every instance includes a robust `permission_callback`.\n\nFor further information on securing WordPress plugins, you can refer to the [WordPress Plugin Handbook on REST API Security](https:\u002F\u002Fdeveloper.wordpress.org\u002Frest-api\u002Fextending-the-rest-api\u002Fadding-custom-endpoints\u002F#permissions-callback).","The Devs Accounting plugin for WordPress is vulnerable to unauthenticated data deletion because it fails to implement a permission callback on its account deletion REST API endpoint. This allows unauthenticated attackers to soft-delete arbitrary accounting records from the database by performing a simple GET request with a targeted account ID.","\u002F\u002F From the vulnerability description and research plan analysis\nregister_rest_route( 'devs-accounting\u002Fv1', '\u002Fdelete-account\u002F(?P\u003Cid>\\d+)', array(\n    'methods'             => 'GET',\n    'callback'            => 'delete_single_account',\n    \u002F\u002F Missing permission_callback allows public access\n));","--- a\u002Fincludes\u002Fapi-routes.php\n+++ b\u002Fincludes\u002Fapi-routes.php\n@@ -10,6 +10,9 @@\n register_rest_route( 'devs-accounting\u002Fv1', '\u002Fdelete-account\u002F(?P\u003Cid>\\d+)', array(\n     'methods'             => 'GET',\n     'callback'            => 'delete_single_account',\n+    'permission_callback' => function() {\n+        return current_user_can( 'manage_options' );\n+    },\n ));","The vulnerability is exploited by sending a standard HTTP GET request to the site's REST API endpoint: `\u002Fwp-json\u002Fdevs-accounting\u002Fv1\u002Fdelete-account\u002F{id}`, where `{id}` is the numeric identifier of the accounting record to be deleted. No authentication or specific payload shape is required because the endpoint registration lacks a 'permission_callback', causing WordPress to skip authorization checks before executing the 'delete_single_account' function. This allows any user to perform an Insecure Direct Object Reference (IDOR) attack to delete records in the 'wp_dac_accounts' table.","gemini-3-flash-preview","2026-06-25 19:26:04","2026-06-25 19:26:45",{"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\u002Fdevs-accounting\u002Ftags"]