CVE-2026-9172

Devs Accounting <= 1.2.0 - Missing Authorization to Unauthenticated Account Deletion via /delete-account/ REST Endpoint

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The Devs Accounting – Simple Accounting and Invoicing Solution plugin for WordPress is vulnerable to unauthorized modification/deletion 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/v1/delete-account/(?P<id>\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.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.2.0
PublishedJune 23, 2026
Last updatedJune 24, 2026
Affected plugindevs-accounting
Research Plan
Unverified

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. ### Security Analysis: Missing Authorization in …

Show full research plan

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.

Security Analysis: Missing Authorization in WordPress REST APIs

In 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.

The Vulnerability Mechanism

The vulnerability described (Missing Authorization) typically occurs when the permission_callback argument is omitted or set to __return_true in the register_rest_route() call.

// Vulnerable Example
register_rest_route( 'devs-accounting/v1', '/delete-account/(?P<id>\d+)', array(
    'methods'             => 'GET', // Or WP_REST_Server::READABLE
    'callback'            => 'delete_single_account',
    // Missing permission_callback allows public access
));

By 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.

Insecure Direct Object Reference (IDOR)

This 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.

Defensive Implementation and Remediation

To secure REST API endpoints, developers must implement a permission_callback that verifies the user's capabilities.

1. Implementing Permission Callbacks

The permission_callback should return true if the user is authorized and a WP_Error or false otherwise.

// Secure Example
register_rest_route( 'devs-accounting/v1', '/delete-account/(?P<id>\d+)', array(
    'methods'             => 'POST', // Sensitive actions should use POST/DELETE, not GET
    'callback'            => 'delete_single_account',
    'permission_callback' => function( $request ) {
        // Only allow users with the 'manage_options' capability
        return current_user_can( 'manage_options' );
    },
));

2. Using Proper HTTP Methods

The vulnerability description notes the use of a GET request for deletion. According to REST principles and security best practices:

  • GET should only be used for retrieving data (idempotent operations).
  • 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.

3. Internal Capability Checks

As a "defense in depth" measure, the callback function itself should also verify permissions before executing database operations:

function delete_single_account( $data ) {
    if ( ! current_user_can( 'manage_options' ) ) {
        return new WP_Error( 'rest_forbidden', __( 'You do not have permission to delete accounts.' ), array( 'status' => 401 ) );
    }
    
    $account_id = $data['id'];
    // Proceed with soft-delete logic...
}

Auditing for Similar Vulnerabilities

Security 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.

For further information on securing WordPress plugins, you can refer to the WordPress Plugin Handbook on REST API Security.

Research Findings
Static analysis — not yet PoC-verified

Summary

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.

Vulnerable Code

// From the vulnerability description and research plan analysis
register_rest_route( 'devs-accounting/v1', '/delete-account/(?P<id>\d+)', array(
    'methods'             => 'GET',
    'callback'            => 'delete_single_account',
    // Missing permission_callback allows public access
));

Security Fix

--- a/includes/api-routes.php
+++ b/includes/api-routes.php
@@ -10,6 +10,9 @@
 register_rest_route( 'devs-accounting/v1', '/delete-account/(?P<id>\d+)', array(
     'methods'             => 'GET',
     'callback'            => 'delete_single_account',
+    'permission_callback' => function() {
+        return current_user_can( 'manage_options' );
+    },
 ));

Exploit Outline

The vulnerability is exploited by sending a standard HTTP GET request to the site's REST API endpoint: `/wp-json/devs-accounting/v1/delete-account/{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.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.