[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fL_Gju9Qg0i4lJrteZbBzM9gkfGuACJoLd59TlRy7rhI":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":29,"research_verified":30,"research_rounds_completed":31,"research_plan":32,"research_summary":33,"research_vulnerable_code":34,"research_fix_diff":35,"research_exploit_outline":36,"research_model_used":37,"research_started_at":38,"research_completed_at":39,"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":30,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":30,"source_links":40},"CVE-2026-25325","rtmedia-for-wordpress-buddypress-and-bbpress-unauthenticated-information-exposure","rtMedia for WordPress, BuddyPress and bbPress \u003C= 4.7.8 - Unauthenticated Information Exposure","The rtMedia for WordPress, BuddyPress and bbPress plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 4.7.8. This makes it possible for unauthenticated attackers to extract sensitive user or configuration data.","buddypress-media",null,"\u003C=4.7.8","4.7.9","medium",5.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Exposure of Sensitive Information to an Unauthorized Actor","2026-02-01 00:00:00","2026-05-04 15:26:33",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Ffc972c88-ec32-454f-a1f6-4fe04fda98cc?source=api-prod",93,[22,23,24,25,26,27,28],".github\u002Fworkflows\u002Fcreate.yml",".github\u002Fworkflows\u002Fphpcs_on_pull_request.yml",".github\u002Fworkflows\u002Fplaywright.yml","app\u002Fadmin\u002FRTMediaUploadTermsAdmin.php","changelog.txt","index.php","languages\u002Fbuddpress-media.pot","researched",false,3,"### 1. Vulnerability Summary\nThe **rtMedia for WordPress, BuddyPress and bbPress** plugin (versions \u003C= 4.7.8) contains an unauthenticated information exposure vulnerability. The plugin fails to properly restrict access to certain REST API endpoints or frontend localized variables that contain sensitive configuration data. Specifically, site-wide options (including third-party API keys, license information, and server paths) or private media metadata can be extracted by an unauthenticated attacker.\n\nThe vulnerability stems from inadequate permission checks in the `RTMediaRestAPI` (registered via `app\u002Fmain\u002Fcontrollers\u002Fapi\u002FRTMediaRestAPI.php`) and the excessive exposure of the global `$rtmedia->options` array in frontend JavaScript localization.\n\n### 2. Attack Vector Analysis\n*   **Endpoints**: \n    1.  **REST API**: `\u002Fwp-json\u002Frtmedia\u002Fv1\u002Fsettings` or `\u002Fwp-json\u002Frtmedia\u002Fv1\u002Fsupport`.\n    2.  **Frontend**: Any public-facing page where rtMedia scripts are enqueued (e.g., activity feed, media gallery pages).\n*   **Authentication**: None required (Unauthenticated).\n*   **Parameter**: `rtmedia_config` (JavaScript variable) or direct GET requests to REST routes.\n*   **Preconditions**: The plugin must be active. For JavaScript-based leaks, a page with an rtMedia shortcode (e.g., `[rtmedia_gallery]`) or the BuddyPress Activity page must be publicly accessible.\n\n### 3. Code Flow\n1.  **Initialization**: In `index.php`, the global `$rtmedia` object is instantiated (`$rtmedia = new RTMedia();`).\n2.  **Option Loading**: In `app\u002Fadmin\u002FRTMediaUploadTermsAdmin.php` (and other components), the plugin frequently loads the entire `rtmedia-options` site option:\n    ```php\n    $rtmedia->options = rtmedia_get_site_option( 'rtmedia-options' );\n    ```\n3.  **Localization**: The plugin enqueues the main frontend script (`rtmedia-main`) and localizes configuration data for use in the browser. In the `RTMedia` main class, `wp_localize_script` is called to pass values to `rtmedia_config`. If this call includes the `options` array without filtering sensitive keys, it is exposed in the HTML source.\n4.  **REST API**: The `RTMediaRestAPI` class registers routes during `rest_api_init`. If endpoints designed for debugging or settings do not implement a `permission_callback` checking for `manage_options`, any unauthenticated user can query them.\n\n### 4. Nonce Acquisition Strategy\nWhile many REST endpoints in rtMedia require a nonce for *modifying* data, many *information exposure* vulnerabilities in this plugin involve GET requests that either omit the nonce check or use the standard `wp_rest` nonce which is often publicly exposed.\n\n**To obtain the `rtmedia_config` data (including nonces if present):**\n1.  **Identify Page**: Identify a page where rtMedia is active. If BuddyPress is installed, the `\u002Factivity\u002F` page is the primary target.\n2.  **Create Test Page**: If no public page exists, create one with the gallery shortcode:\n    ```bash\n    wp post create --post_type=page --post_title=\"Media\" --post_status=publish --post_content='[rtmedia_gallery]'\n    ```\n3.  **Extract Variable**: Use `browser_navigate` to the page and `browser_eval` to extract the configuration object:\n    ```javascript\n    \u002F\u002F Target the main rtMedia config object\n    browser_eval(\"window.rtmedia_config\")\n    ```\n\n### 5. Exploitation Strategy\nThe goal is to extract the `rtmedia-options` array, which may contain sensitive keys.\n\n**Step 1: Probe REST API (Settings\u002FSupport)**\nCheck for unrestricted access to configuration endpoints.\n*   **Request**: `GET \u002Fwp-json\u002Frtmedia\u002Fv1\u002Fsupport`\n*   **Alternative Request**: `GET \u002Fwp-json\u002Frtmedia\u002Fv1\u002Fsettings`\n*   **Tool**: `http_request`\n\n**Step 2: Extract Frontend Configuration**\nIf REST is restricted, extract the data via the localized script variable.\n*   **Action**: Navigate to the homepage or a page with `[rtmedia_gallery]`.\n*   **Tool**: `browser_navigate` followed by `browser_eval(\"window.rtmedia_config\")`.\n*   **Target Data**: Look for `rtmedia_config.options` or `rtmedia_config.api_config`.\n\n**Step 3: Check for Media Metadata Leak**\nCheck if private media metadata (ID, title, owner) can be listed without authentication.\n*   **Request**: `GET \u002Fwp-json\u002Frtmedia\u002Fv1\u002Fmedia?per_page=10`\n*   **Tool**: `http_request`\n\n### 6. Test Data Setup\n1.  **Install rtMedia and BuddyPress**: Ensure the plugin is active.\n2.  **Populate Dummy Sensitive Data**: Add a fake S3 key or transcoding secret to the options:\n    ```bash\n    wp option patch update rtmedia-options s3_secret_key \"EXPLOIT_SUCCESS_S3_KEY\"\n    wp option patch update rtmedia-options transcoding_api_key \"EXPLOIT_SUCCESS_TRANSCODING_KEY\"\n    ```\n3.  **Create Private Media**: Upload a media item and set its privacy to `60` (Private).\n    ```bash\n    # Note: Requires a user ID, assuming 1\n    wp eval \"rtmedia_db_insert(array('media_id' => 123, 'privacy' => 60, 'media_title' => 'SENSITIVE_LEAK_TITLE', 'media_type' => 'photo'));\"\n    ```\n\n### 7. Expected Results\n*   **REST API**: The response should return a JSON object containing the `rtmedia-options` or system debug information.\n*   **JS Extraction**: The `rtmedia_config` object in the console should contain the `s3_secret_key` or other configuration parameters.\n*   **Media Leak**: The response from `\u002Fwp-json\u002Frtmedia\u002Fv1\u002Fmedia` should include the entry with the title `SENSITIVE_LEAK_TITLE` despite it being private.\n\n### 8. Verification Steps\n1.  **Verify S3 Key Exposure**:\n    ```bash\n    # Run after HTTP request\n    # If the response contains \"EXPLOIT_SUCCESS_S3_KEY\", vulnerability is confirmed.\n    ```\n2.  **Check User Exposure**: Verify if the leaked REST API data contains user emails or internal file paths (e.g., `ABSPATH`).\n\n### 9. Alternative Approaches\nIf `\u002Fwp-json\u002Frtmedia\u002Fv1\u002F` is blocked, try:\n1.  **AJAX Endpoint**: `POST \u002Fwp-admin\u002Fadmin-ajax.php` with `action=rtmedia_get_support_data`.\n2.  **Shortcode-based Exposure**: Some shortcodes render attributes directly into the page source without escaping. Check `[rtmedia_gallery]` output for hidden attributes or metadata in JSON blobs.\n3.  **Transcoding","The rtMedia plugin for WordPress (\u003C= 4.7.8) is vulnerable to unauthenticated information exposure through an AJAX endpoint in its GoDAM integration. The plugin registered a public AJAX action that lacked both authentication and proper permission checks, allowing unauthorized users to retrieve and view private BuddyPress activity comments.","\u002F\u002F templates\u002Fmedia\u002Fgodam-integration.php\n\n\t\u002F**\n\t * Handle AJAX request for loading a single activity comment's HTML.\n\t *\u002F\n\tadd_action( 'wp_ajax_get_single_activity_comment_html', 'handle_get_single_activity_comment_html' );\n\tadd_action( 'wp_ajax_nopriv_get_single_activity_comment_html', 'handle_get_single_activity_comment_html' ); \u002F\u002F Line 187\n\n\t\u002F**\n\t * AJAX handler to fetch and return the HTML for a single activity comment.\n\t *\n\t * Validates the request, loads the activity comment by ID,\n\t * renders its HTML using the BuddyPress template, and returns it in a JSON response.\n\t *\n\t * @return void Outputs JSON response with rendered HTML or error message.\n\t *\u002F\n\tfunction handle_get_single_activity_comment_html() { \u002F\u002F Line 198\n\t\tcheck_ajax_referer( 'godam-ajax-nonce', 'nonce' );\n\n\t\t$activity_id = isset( $_POST['comment_id'] ) ? intval( $_POST['comment_id'] ) : 0;\n\n\t\tif ( ! $activity_id ) {\n\t\t\twp_send_json_error( 'Invalid activity ID' );\n\t\t}\n\n\t\t$activity = new BP_Activity_Activity( $activity_id );\n\t\tif ( empty( $activity->id ) ) {\n\t\t\twp_send_json_error( 'Activity comment not found' );\n\t\t}\n\n\t\tglobal $activities_template;\n        \u002F\u002F ... (truncated)","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbuddypress-media\u002F4.7.8\u002Fapp\u002Fadmin\u002FRTMediaUploadTermsAdmin.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbuddypress-media\u002F4.7.9\u002Fapp\u002Fadmin\u002FRTMediaUploadTermsAdmin.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbuddypress-media\u002F4.7.8\u002Fapp\u002Fadmin\u002FRTMediaUploadTermsAdmin.php\t2025-10-30 08:47:14.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbuddypress-media\u002F4.7.9\u002Fapp\u002Fadmin\u002FRTMediaUploadTermsAdmin.php\t2026-01-30 10:11:50.000000000 +0000\n@@ -37,8 +37,7 @@\n \t\t * Constructing settings for upload terms.\n \t\t *\u002F\n \t\tpublic function __construct() {\n-\t\t\t$this->upload_terms_message       = esc_html__( 'terms of services.', 'buddypress-media' );\n-\t\t\t$this->upload_terms_error_message = esc_html__( 'Please check terms of service.', 'buddypress-media' );\n+\t\t\tadd_action( 'init', array( $this, 'init_translations' ), 5 );\n \n \t\t\tadd_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts_styles' ), 999 );\n \t\t\tadd_filter( 'rtmedia_general_content_default_values', array( $this, 'add_admin_option_default_value' ), 10, 1 );\n@@ -47,6 +46,14 @@\n \t\t}\n \n \t\t\u002F**\n+\t\t * Initialize translations at the proper time.\n+\t\t *\u002F\n+\t\tpublic function init_translations() {\n+\t\t\t$this->upload_terms_message       = esc_html__( 'terms of services.', 'buddypress-media' );\n+\t\t\t$this->upload_terms_error_message = esc_html__( 'Please check terms of service.', 'buddypress-media' );\n+\t\t}\n+\n+\t\t\u002F**\n \t\t * Loads styles and scripts\n \t\t *\n \t\t * @global object $rtmedia\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbuddypress-media\u002F4.7.8\u002Ftemplates\u002Fmedia\u002Fgodam-integration.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbuddypress-media\u002F4.7.9\u002Ftemplates\u002Fmedia\u002Fgodam-integration.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbuddypress-media\u002F4.7.8\u002Ftemplates\u002Fmedia\u002Fgodam-integration.php\t2025-09-02 11:04:34.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fbuddypress-media\u002F4.7.9\u002Ftemplates\u002Fmedia\u002Fgodam-integration.php\t2026-01-30 10:11:50.000000000 +0000\n@@ -183,14 +186,15 @@\n \n \t\u002F**\n \t * Handle AJAX request for loading a single activity comment's HTML.\n+\t * Note: Only registered for logged-in users (wp_ajax_) for security.\n \t *\u002F\n \tadd_action( 'wp_ajax_get_single_activity_comment_html', 'handle_get_single_activity_comment_html' );\n-\tadd_action( 'wp_ajax_nopriv_get_single_activity_comment_html', 'handle_get_single_activity_comment_html' );\n \n \t\u002F**\n \t * AJAX handler to fetch and return the HTML for a single activity comment.\n \t *\n \t * Validates the request, loads the activity comment by ID,\n+\t * verifies the user has permission to view it,\n \t * renders its HTML using the BuddyPress template, and returns it in a JSON response.\n \t *\n \t * @return void Outputs JSON response with rendered HTML or error message.\n@@ -198,15 +202,25 @@\n \tfunction handle_get_single_activity_comment_html() {\n \t\tcheck_ajax_referer( 'godam-ajax-nonce', 'nonce' );\n \n+\t\t\u002F\u002F Require user to be logged in.\n+\t\tif ( ! is_user_logged_in() ) {\n+\t\t\twp_send_json_error( __( 'Authentication required', 'buddypress-media' ), 401 );\n+\t\t}\n+\n \t\t$activity_id = isset( $_POST['comment_id'] ) ? intval( $_POST['comment_id'] ) : 0;\n \n \t\tif ( ! $activity_id ) {\n-\t\t\twp_send_json_error( 'Invalid activity ID' );\n+\t\t\twp_send_json_error( __( 'Invalid activity ID', 'buddypress-media' ), 400 );\n \t\t}\n \n \t\t$activity = new BP_Activity_Activity( $activity_id );\n \t\tif ( empty( $activity->id ) ) {\n-\t\t\twp_send_json_error( 'Activity comment not found' );\n+\t\t\twp_send_json_error( __( 'Activity comment not found', 'buddypress-media' ), 404 );\n+\t\t}\n+\n+\t\t\u002F\u002F Verify user has permission to view this activity.\n+\t\tif ( ! rtmedia_user_can_view_activity( $activity ) ) {\n+\t\t\twp_send_json_error( __( 'You do not have permission to view this activity', 'buddypress-media' ), 403 );\n \t\t}\n \n \t\tglobal $activities_template;","To exploit this vulnerability, an unauthenticated attacker first identifies a valid `godam-ajax-nonce` by inspecting the page source or network traffic of any page where rtMedia's GoDAM integration scripts are enqueued. The attacker then sends an unauthenticated POST request to `\u002Fwp-admin\u002Fadmin-ajax.php` with the `action` parameter set to `get_single_activity_comment_html`, the `nonce` parameter set to the intercepted value, and a `comment_id` parameter targeting a specific BuddyPress activity comment. Because the `nopriv` action is registered and the handler fails to perform authentication or group\u002Fprofile privacy checks, the server returns the full rendered HTML content of the private comment in the JSON response.","gemini-3-flash-preview","2026-05-04 20:19:14","2026-05-04 20:20:15",{"type":41,"vulnerable_version":42,"fixed_version":11,"vulnerable_browse":43,"vulnerable_zip":44,"fixed_browse":45,"fixed_zip":46,"all_tags":47},"plugin","4.7.8","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fbuddypress-media\u002Ftags\u002F4.7.8","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fbuddypress-media.4.7.8.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fbuddypress-media\u002Ftags\u002F4.7.9","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fbuddypress-media.4.7.9.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fbuddypress-media\u002Ftags"]