[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fvjqiTrDIpXul6Im7WD9nk1XKynlNZcM7k6KM0gP91KQ":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-2025-62104","acf-galerie-4-missing-authorization","ACF Galerie 4 \u003C= 1.4.2 - Missing Authorization","The ACF Galerie 4 plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.4.2. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.","acf-galerie-4",null,"\u003C=1.4.2","1.4.3","medium",4.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Missing Authorization","2026-04-23 00:00:00","2026-04-30 14:38:01",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F37d204b5-ffdb-4e0d-9f7b-2c2b70b1bab1?source=api-prod",8,[22,23,24],"acf-galerie-4.php","providers\u002Fclass.migration.php","readme.txt","researched",false,3,"# Vulnerability Research Plan: CVE-2025-62104 (ACF Galerie 4 - Missing Authorization)\n\n## 1. Vulnerability Summary\nThe **ACF Galerie 4** plugin (versions \u003C= 1.4.2) contains a missing authorization vulnerability in its migration functionality. Specifically, the AJAX handler `acfg4_start_migration` fails to perform a capability check (e.g., `current_user_can('manage_options')`). While it implements a nonce check, the nonce is exposed to any authenticated user who can access the WordPress admin dashboard (including the Subscriber role). An attacker with Subscriber-level access can trigger this migration process, which modifies existing Advanced Custom Fields (ACF) field definitions in the database, potentially disrupting the site's gallery functionality or altering data format in `wp_postmeta`.\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Action:** `acfg4_start_migration`\n*   **Method:** POST\n*   **Parameters:**\n    *   `action`: `acfg4_start_migration` (Required)\n    *   `nonce`: A valid nonce for the `acfg4_start_migration_nonce` action (Required)\n    *   `migrate_from`: Either `1` (ACF Photo Gallery Field) or `2` (ACF Gallery Pro) (Required)\n*   **Required Authentication:** Subscriber or higher (Authenticated).\n*   **Preconditions:** The plugin must be active. For the migration to have a visible effect, existing ACF fields of type `photo_gallery` or `gallery` should exist.\n\n## 3. Code Flow\n1.  **Registration:** In `acf-galerie-4.php`, the `initialize_migration()` function instantiates the `acfg4_migration` class.\n2.  **Hooking:** In `providers\u002Fclass.migration.php`, the constructor registers the AJAX action:\n    `add_action('wp_ajax_acfg4_start_migration', array($this, 'acfg4_start_migration'));`\n3.  **Nonce Exposure:** The function `acfg4_start_migration_nonce()` is hooked to `admin_head`. It checks `if ( !is_admin() ) return;`. Since the WordPress dashboard (`\u002Fwp-admin\u002F`) is accessible to Subscribers, this function executes for them, printing:\n    `\u003Cscript type=\"text\u002Fjavascript\">const acfg4_start_migration_nonce = \"...\";\u003C\u002Fscript>`\n4.  **Vulnerable Function:** The `acfg4_start_migration()` function:\n    *   Verifies the nonce via `wp_verify_nonce( $_POST['nonce'], 'acfg4_start_migration_nonce')`.\n    *   Checks if `migrate_from` is `1` or `2`.\n    *   **Crucially**, it skips any `current_user_can()` check.\n    *   It queries `wp_posts` for `post_type = 'acf-field'`.\n    *   Iterates through fields and updates `post_content` (serialized metadata) if the field type is `photo_gallery` or `gallery`, changing it to `galerie-4`.\n    *   If `migrate_from == 1`, it also performs a regex-like migration on `wp_postmeta` associated with those fields.\n\n## 4. Nonce Acquisition Strategy\nThe nonce is printed directly into the HTML of any admin page for a logged-in user.\n1.  **Login:** Log in as a Subscriber.\n2.  **Navigate:** Navigate to `\u002Fwp-admin\u002Fprofile.php` (standard landing page for Subscribers).\n3.  **Extract:** Use `browser_eval` to extract the global JavaScript variable.\n4.  **Target Variable:** `window.acfg4_start_migration_nonce`\n\n## 5. Exploitation Strategy\n1.  **Data Setup:** Create a test ACF field with type `gallery` (representing ACF Pro) or `photo_gallery` (representing the ACF Photo Gallery plugin).\n2.  **Authentication:** Authenticate as a Subscriber-level user.\n3.  **Nonce Capture:** Navigate to `\u002Fwp-admin\u002Fprofile.php` and run `browser_eval(\"window.acfg4_start_migration_nonce\")`.\n4.  **Trigger Migration:** Perform a POST request to `admin-ajax.php` using the `http_request` tool.\n\n**Request Details:**\n*   **URL:** `{{BASE_URL}}\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Method:** POST\n*   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n*   **Body:**\n    ```text\n    action=acfg4_start_migration&nonce={{NONCE}}&migrate_from=2\n    ```\n    *(Using `migrate_from=2` to trigger the basic field type update)*.\n\n## 6. Test Data Setup\n1.  **User:** A user with the role `subscriber`.\n2.  **ACF Field:** Since the plugin migrates existing fields, we must create an ACF field manually via WP-CLI to act as the \"victim\" data.\n    ```bash\n    # Create an ACF Field Group\n    FIELD_GROUP_ID=$(wp post create --post_type=acf-field-group --post_title=\"Test Gallery Group\" --post_status=publish --porcelain)\n\n    # Create an ACF Field of type 'gallery' (simulating ACF Pro Gallery)\n    # The 'post_content' must be a serialized array containing 'type' => 'gallery'\n    FIELD_DATA='a:1:{s:4:\"type\";s:7:\"gallery\";}'\n    wp post create --post_type=acf-field --post_excerpt=\"my_gallery_field\" --post_content=\"$FIELD_DATA\" --post_parent=$FIELD_GROUP_ID --post_status=publish\n    ```\n\n## 7. Expected Results\n*   The AJAX response should be: `{\"success\":true,\"data\":{\"message\":\"Migration has successfully completed.\"}}`\n*   The database record for the ACF field created in the setup phase should have its `post_content` updated.\n\n## 8. Verification Steps\n1.  **Check Post Content:** Use WP-CLI to inspect the `post_content` of the ACF field.\n    ```bash\n    wp db query \"SELECT post_content FROM wp_posts WHERE post_type = 'acf-field' AND post_excerpt = 'my_gallery_field'\"\n    ```\n2.  **Verify Transformation:** Confirm that the serialized string now contains `s:9:\"galerie-4\"` instead of `s:7:\"gallery\"`.\n    *   Before: `a:1:{s:4:\"type\";s:7:\"gallery\";}`\n    *   After: `a:1:{s:4:\"type\";s:9:\"galerie-4\";}`\n\n## 9. Alternative Approaches\nIf the Subscriber cannot access `\u002Fwp-admin\u002Fprofile.php` due to other security plugins:\n*   The nonce is also enqueued via `acfg4_start_migration_nonce` in `admin_head`. If any other plugin page is accessible to Subscribers (e.g., a custom dashboard page), the nonce will be there.\n*   Check if `migrate_from=1` produces observable changes in `wp_postmeta`. If a post has metadata associated with the field name `my_gallery_field`, the migration will attempt to serialize comma-separated values into a PHP array.\n    *   Setup meta: `wp post meta add [POST_ID] my_gallery_field \"123,456,789\"`\n    *   After Exploit: `wp post meta get [POST_ID] my_gallery_field` should return a serialized array `a:3:{i:0;s:3:\"123\";i:1;s:3:\"456\";i:2;s:3:\"789\";}`.","The ACF Galerie 4 plugin for WordPress (versions \u003C= 1.4.2) fails to perform a capability check in its AJAX migration handler. This allow authenticated users, including those with Subscriber-level access, to trigger a migration process that alters ACF field definitions and transforms post metadata in the database.","\u002F\u002F providers\u002Fclass.migration.php\n\n    function acfg4_start_migration_nonce() {\n        if ( !is_admin() ) return;\n        $nonce = wp_create_nonce('acfg4_start_migration_nonce');\n    ?>\n        \u003Cscript type=\"text\u002Fjavascript\">const acfg4_start_migration_nonce = \"\u003C?php echo $nonce; ?>\";\u003C\u002Fscript>\n    \u003C?php\n    }\n\n---\n\n\u002F\u002F providers\u002Fclass.migration.php, around line 37\n\n    public function acfg4_start_migration() {\n        global $wpdb;\n        $wpdb->query('START TRANSACTION');\n\n        try {\n            $migrate_from = $_POST['migrate_from'];\n\n            if (\n                isset( $_POST['nonce'] ) &&\n                !wp_verify_nonce( $_POST['nonce'], 'acfg4_start_migration_nonce') )\n            {\n                wp_send_json_error(['message' => \"Nonce verification failed. Please try again.\"], 400);\n            }\n\n            if( !in_array( $migrate_from, [1, 2] ) ){\n                wp_send_json_error(['message' => \"Choose which plugin you want to migrate from.\"], 400);\n            }\n\n            $fields = $wpdb->get_results(\"SELECT * FROM {$wpdb->posts} WHERE post_type = 'acf-field'\");\n\n            foreach( $fields as $field ){\n                $field_name = $field->post_excerpt;\n                $field_metadata = unserialize( $field->post_content );\n                $field_type = $field_metadata['type'];\n\n                if( in_array( $field_type, ['photo_gallery', 'gallery'])){\n                    $field_metadata['type'] = 'galerie-4'; \n                    $updated_content = serialize($field_metadata);\n\n                    $wpdb->update(\n                        $wpdb->posts,\n                        array( 'post_content' => $updated_content ),\n                        array( 'ID' => $field->ID )\n                    );\n...","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Facf-galerie-4\u002F1.4.2\u002Fproviders\u002Fclass.migration.php\t2025-02-10 06:44:00.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Facf-galerie-4\u002F1.4.3\u002Fproviders\u002Fclass.migration.php\t2025-12-20 23:27:00.000000000 +0000\n@@ -18,7 +18,7 @@\n     }\n     \n     function acfg4_start_migration_nonce() {\n-        if ( !is_admin() ) return;\n+        if ( ! current_user_can('manage_options') ) return;\n         $nonce = wp_create_nonce('acfg4_start_migration_nonce');\n     ?>\n         \u003Cscript type=\"text\u002Fjavascript\">const acfg4_start_migration_nonce = \"\u003C?php echo $nonce; ?>\";\u003C\u002Fscript>\n@@ -26,27 +26,41 @@\n     }\n \n     public function enqueue_plugin_admin_scripts() {\n-        wp_enqueue_script('acfg4-admin-script', ACFG4_PLUGIN_URL . 'assets\u002Fjs\u002Fadmin-script.js', ['jquery'], '1.0.0', true);\n+        if ( current_user_can('manage_options') ) {\n+            wp_enqueue_script('acfg4-admin-script', ACFG4_PLUGIN_URL . 'assets\u002Fjs\u002Fadmin-script.js', ['jquery'], '1.0.0', true);\n+        }\n     }\n \n     public function enqueue_plugin_admin_styles() {\n-        wp_enqueue_style('acfg4-admin-css', ACFG4_PLUGIN_URL . 'assets\u002Fcss\u002Fadmin-style.css', [], '1.0.0');\n+        if ( current_user_can('manage_options') ) {\n+            wp_enqueue_style('acfg4-admin-css', ACFG4_PLUGIN_URL . 'assets\u002Fcss\u002Fadmin-style.css', [], '1.0.0');\n+        }\n     }\n \n     public function acfg4_start_migration() {\n+        if ( ! current_user_can('manage_options') ) {\n+            wp_send_json_error(\n+                ['message' => 'Unauthorized'],\n+                403\n+            );\n+        }\n+        \n+        if (\n+            ! isset($_POST['nonce']) ||\n+            ! wp_verify_nonce($_POST['nonce'], 'acfg4_start_migration_nonce')\n+        ) {\n+            wp_send_json_error(\n+                ['message' => 'Invalid or missing nonce'],\n+                400\n+            );\n+        }\n+\n         global $wpdb;\n         $wpdb->query('START TRANSACTION');\n \n         try {\n             $migrate_from = $_POST['migrate_from'];\n \n-            if (\n-                isset( $_POST['nonce'] ) &&\n-                !wp_verify_nonce( $_POST['nonce'], 'acfg4_start_migration_nonce') )\n-            {\n-                wp_send_json_error(['message' => \"Nonce verification failed. Please try again.\"], 400);\n-            }\n-\n             if( !in_array( $migrate_from, [1, 2] ) ){\n                 wp_send_json_error(['message' => \"Choose which plugin you want to migrate from.\"], 400);\n             }","To exploit this vulnerability, an attacker first logs into the WordPress site as a Subscriber. They then access any administrative page (such as \u002Fwp-admin\u002Fprofile.php) to obtain the 'acfg4_start_migration_nonce', which is automatically printed into the page's HTML for any user in the admin area. Once the nonce is acquired, the attacker makes a POST request to \u002Fwp-admin\u002Fadmin-ajax.php with the 'action' parameter set to 'acfg4_start_migration', the 'nonce' parameter populated with the captured nonce, and 'migrate_from' set to 1 or 2. This triggers the acfg4_start_migration function, which proceeds to update ACF field definitions in the wp_posts table and potentially re-serializes gallery data in the wp_postmeta table without verifying that the user has the 'manage_options' capability.","gemini-3-flash-preview","2026-05-04 18:42:10","2026-05-04 18:42:30",{"type":37,"vulnerable_version":38,"fixed_version":11,"vulnerable_browse":39,"vulnerable_zip":40,"fixed_browse":41,"fixed_zip":42,"all_tags":43},"plugin","1.4.2","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Facf-galerie-4\u002Ftags\u002F1.4.2","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Facf-galerie-4.1.4.2.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Facf-galerie-4\u002Ftags\u002F1.4.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Facf-galerie-4.1.4.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Facf-galerie-4\u002Ftags"]