[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fpFeb-Oh0A_JE25goydsJaMLRawdcmcuO8xc9c9kl2jk":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":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":35,"research_fix_diff":36,"research_exploit_outline":37,"research_model_used":38,"research_started_at":39,"research_completed_at":40,"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":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":41},"CVE-2026-25322","publishpress-revisions-duplicate-posts-submit-approve-and-schedule-content-changes-cross-site-request-forgery","PublishPress Revisions: Duplicate Posts, Submit, Approve and Schedule Content Changes \u003C= 3.7.22 - Cross-Site Request Forgery","The PublishPress Revisions: Duplicate Posts, Submit, Approve and Schedule Content Changes plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to, and including, 3.7.22. This is due to missing or incorrect nonce validation on a function. This makes it possible for unauthenticated attackers to perform an unauthorized action granted they can trick a site administrator into performing an action such as clicking on a link.","revisionary",null,"\u003C=3.7.22","3.7.23","medium",4.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:R\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Cross-Site Request Forgery (CSRF)","2026-01-29 00:00:00","2026-05-04 15:39:48",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fa2c3a01c-af77-4abc-b33c-b637d55e0be2?source=api-prod",96,[22,23,24,25,26,27,28,29],"CHANGELOG.md","admin\u002Fadmin-init_rvy.php","admin\u002Fadmin-posts_rvy.php","admin\u002Fagents_checklist_rvy.php","admin\u002Foptions.php","admin\u002Fpost-edit-block-ui_rvy.php","admin\u002Fpost-edit_rvy.php","admin\u002Fpost-editor-workflow-ui_rvy.php","researched",false,3,"# Vulnerability Research Plan: CVE-2026-25322 (PublishPress Revisions CSRF)\n\n## 1. Vulnerability Summary\nThe **PublishPress Revisions** plugin (up to 3.7.22) is vulnerable to **Cross-Site Request Forgery (CSRF)** due to missing nonce validation in the `rvy_admin_init()` function located in `admin\u002Fadmin-init_rvy.php`. This function handles the updating of plugin settings. Specifically, when the `rvy_submit` POST parameter is present, the plugin proceeds to save configuration options without verifying a security nonce. This allows an unauthenticated attacker to change site-wide revision settings by tricking an administrator into submitting a forged request.\n\n## 2. Attack Vector Analysis\n- **Vulnerable Endpoint**: Any administrative URL (e.g., `\u002Fwp-admin\u002Fadmin.php?page=revisionary-settings`), as the vulnerable function is hooked to `admin_init`.\n- **Action**: Plugin settings update.\n- **Vulnerable Parameter**: `rvy_submit`.\n- **Required Authentication**: Administrator (the victim must have an active session).\n- **Preconditions**: The attacker must trick the administrator into clicking a link or visiting a malicious page that triggers a POST request to the WordPress admin panel.\n\n## 3. Code Flow\n1. **Hook Registration**: The plugin likely registers `rvy_admin_init` on the `admin_init` hook (standard WordPress behavior for functions named `*_admin_init`).\n2. **Entry Point**: `admin\u002Fadmin-init_rvy.php:49`\n   ```php\n   if ( ! empty($_POST['rvy_submit']) || ! empty($_POST['rvy_defaults']) ) {\n       require_once( RVY_ABSPATH . '\u002Fsubmittee_rvy.php');\t\n       $handler = new Revisionary_Submittee();\n   \n       if ( isset($_POST['rvy_submit']) ) {\n           $sitewide = isset($_POST['rvy_options_doing_sitewide']);\n           $customize_defaults = isset($_POST['rvy_options_customize_defaults']);\n           $handler->handle_submission( 'update', $sitewide, $customize_defaults );\n       }\n       \u002F\u002F ...\n   }\n   ```\n3. **Missing Validation**: Notice that between line 49 and line 57, there is **no call** to `check_admin_referer()` or `wp_verify_nonce()`.\n4. **Execution**: The `Revisionary_Submittee::handle_submission` method (in `submittee_rvy.php`) iterates through the `$_POST` data and updates the plugin's option (usually stored in the `revisionary_options` array in the database).\n\n## 4. Nonce Acquisition Strategy\n**No nonce is required for this exploit.**\nThe vulnerability exists specifically because the plugin fails to check for a nonce before processing the `rvy_submit` action. An attacker can submit the request with zero knowledge of site secrets or nonces.\n\n## 5. Exploitation Strategy\nThe goal is to change a visible setting, such as the `revision_limit_per_post`, to prove unauthorized modification of plugin configuration.\n\n### HTTP Request (PoC)\nThe security agent will perform an authenticated POST request as an Administrator (simulating the victim's browser being hijacked via CSRF).\n\n- **URL**: `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin.php?page=revisionary-settings`\n- **Method**: `POST`\n- **Content-Type**: `application\u002Fx-www-form-urlencoded`\n- **Body**:\n  ```text\n  rvy_submit=1&revision_limit_per_post=1337&pending_revisions=1\n  ```\n- **Tool**: `http_request`\n\n## 6. Test Data Setup\n1. **Install Plugin**: Ensure PublishPress Revisions \u003C= 3.7.22 is active.\n2. **Check Current State**:\n   ```bash\n   wp option get revisionary_options\n   ```\n   (Identify if `revision_limit_per_post` is currently set to something other than `1337`).\n\n## 7. Expected Results\n- The server should return a `302 Redirect` (standard WordPress admin behavior after saving settings) or a `200 OK` if the redirect is followed.\n- The plugin will process the `handle_submission` call.\n- The `revision_limit_per_post` value in the `revisionary_options` array will be updated to `1337`.\n\n## 8. Verification Steps\nAfter the `http_request` is sent, verify the modification using WP-CLI:\n```bash\n# Get the options and check the specific key\nwp option get revisionary_options --format=json | grep -o '\"revision_limit_per_post\":\"1337\"'\n```\nIf the grep returns a match, the CSRF was successful.\n\n## 9. Alternative Approaches\nIf `revision_limit_per_post` does not update (e.g., if the plugin expects specific input formats), try targeting the `pending_revisions` checkbox or the `copy_posts_capability` setting:\n- **Payload**: `rvy_submit=1&pending_revisions=0` (to disable pending revisions).\n- **Payload**: `rvy_submit=1&revision_queue_capability=subscriber` (to potentially allow lower-privileged users to see the revision queue, if the capability is not strictly validated during save).\n\nNote: checkboxes in WordPress settings often require the value `'1'` to be considered \"checked\" and are absent from POST if unchecked. The exploit should send `rvy_submit=1` plus the target option name and its desired value.","The PublishPress Revisions plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) due to missing nonce validation in the settings processing logic and several AJAX actions. This allows unauthenticated attackers to modify plugin settings or perform unauthorized revision management tasks by tricking an administrator into interacting with a malicious link or page.","\u002F\u002F admin\u002Fadmin-init_rvy.php:66\nif ( ! empty($_POST['rvy_submit']) || ! empty($_POST['rvy_defaults']) ) {\n    require_once( RVY_ABSPATH . '\u002Fsubmittee_rvy.php');\t\n    $handler = new Revisionary_Submittee();\n\n    if ( isset($_POST['rvy_submit']) ) {\n        $sitewide = isset($_POST['rvy_options_doing_sitewide']);\n        $customize_defaults = isset($_POST['rvy_options_customize_defaults']);\n        $handler->handle_submission( 'update', $sitewide, $customize_defaults );\n    }\n    \u002F\u002F ...\n}\n\n---\n\n\u002F\u002F admin\u002Fpost-edit_rvy.php:348 (Example of AJAX CSRF vector without nonce check)\n$(document).on('change', 'div.rvy-author-selection select', function(e) {\n    var data = {'rvy_ajax_field': 'author_select', 'rvy_ajax_value': \u003C?php echo esc_attr($post->ID);?>, 'rvy_selection': $('div.rvy-author-selection select').val(), 'nc': Math.floor(Math.random() * 99999999)};","diff -ru 3.7.22\u002Fadmin\u002Fadmin-init_rvy.php 3.7.23\u002Fadmin\u002Fadmin-init_rvy.php\n--- 3.7.22\u002Fadmin\u002Fadmin-init_rvy.php\t2026-01-08 21:35:36.000000000 +0000\n+++ 3.7.23\u002Fadmin\u002Fadmin-init_rvy.php\t2026-02-03 20:43:52.000000000 +0000\n@@ -66,6 +66,8 @@\n \tif ( ! empty($_POST['rvy_submit']) || ! empty($_POST['rvy_defaults']) ) {\n+\t\tcheck_admin_referer('rvy-update-options');\n \t\trequire_once( RVY_ABSPATH . '\u002Fsubmittee_rvy.php');\t\n \t\t$handler = new Revisionary_Submittee();\ndiff -ru 3.7.22\u002Fadmin\u002Fpost-edit-block-ui_rvy.php 3.7.23\u002Fadmin\u002Fpost-edit-block-ui_rvy.php\n--- 3.7.22\u002Fadmin\u002Fpost-edit-block-ui_rvy.php\t2025-11-17 19:02:04.000000000 +0000\n+++ 3.7.23\u002Fadmin\u002Fpost-edit-block-ui_rvy.php\t2026-02-03 20:43:52.000000000 +0000\n@@ -113,6 +113,11 @@\n             wp_enqueue_script( 'rvy_object_edit', RVY_URLPATH . \"\u002Fadmin\u002Frvy_post-block-edit{$suffix}.js\", array('jquery', 'jquery-form'), PUBLISHPRESS_REVISIONS_VERSION, true );\n \n             $args = \\PublishPress\\Revisions\\PostEditorWorkflowUI::postLinkParams(compact('post', 'do_pending_revisions', 'do_scheduled_revisions'));\n+\n+            $args['createRevisionNonce'] = wp_create_nonce('create_revision');\n+            $args['submitRevisionNonce'] = wp_create_nonce('submit_revision');\n+            $args['createScheduledRevisionNonce'] = wp_create_nonce('create_scheduled_revision');\n+            $args['authorSelectNonce'] = wp_create_nonce('author_select');\n         }\n \n         $wp_timezone = wp_timezone();\n@@ -181,7 +186,7 @@\n             });\n \n             $(document).on('change', 'div.rvy-author-selection select', function(e) {\n-                var data = {'rvy_ajax_field': 'author_select', 'rvy_ajax_value': \u003C?php echo esc_attr($post->ID);?>, 'rvy_selection': $('div.rvy-author-selection select').val(), 'nc': Math.floor(Math.random() * 99999999)};\n+                var data = {'rvy_ajax_field': 'author_select', 'rvy_ajax_value': \u003C?php echo esc_attr($post->ID);?>, 'rvy_selection': $('div.rvy-author-selection select').val(), '_rvynonce': '\u003C?php echo esc_attr(wp_create_nonce('author_select'));?>'};\n \n                 $('div.rvy-author-selection select').attr('disabled', 'disabled');","The exploit targets the plugin's settings update mechanism and various AJAX-based management actions that lack nonce verification. An attacker can craft a POST request to any administrative URL (since the vulnerable function is hooked to 'admin_init'). \n\n1. Methodology: For settings modification, the attacker creates a hidden HTML form that submits to `\u002Fwp-admin\u002Fadmin.php?page=revisionary-settings`. \n2. Payload Shape: The POST body must contain `rvy_submit=1` along with the target option keys and values (e.g., `revision_limit_per_post=1337`). \n3. AJAX Vector: For management actions (like revision creation or author changes), the attacker triggers a request with `rvy_ajax_field=create_revision` and target parameters without providing a `_rvynonce` token.\n4. Requirements: The victim must be a logged-in site administrator who visits a malicious page or clicks a link controlled by the attacker while their session is active.","gemini-3-flash-preview","2026-05-04 21:09:26","2026-05-04 21:09:57",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","3.7.22","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Frevisionary\u002Ftags\u002F3.7.22","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Frevisionary.3.7.22.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Frevisionary\u002Ftags\u002F3.7.23","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Frevisionary.3.7.23.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Frevisionary\u002Ftags"]