[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$feFc0JIvF_ffCAGX4wp0m8QLhAcwk7TzqLlhxRY3-OCs":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":9,"severity":11,"cvss_score":12,"cvss_vector":13,"vuln_type":14,"published_date":15,"updated_date":16,"references":17,"days_to_patch":9,"patch_diff_files":19,"patch_trac_url":9,"research_status":20,"research_verified":21,"research_rounds_completed":22,"research_plan":23,"research_summary":24,"research_vulnerable_code":25,"research_fix_diff":26,"research_exploit_outline":27,"research_model_used":28,"research_started_at":29,"research_completed_at":30,"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":21,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":21,"source_links":31},"CVE-2026-39698","the-publisher-desk-adstxt-missing-authorization","The Publisher Desk ads.txt \u003C= 1.5.0 - Missing Authorization","The The Publisher Desk ads.txt plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.5.0. This makes it possible for unauthenticated attackers to perform an unauthorized action.","the-publisher-desk-ads-txt",null,"\u003C=1.5.0","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-02-27 00:00:00","2026-04-15 21:31:46",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fa58a859d-0274-4d2f-80e3-ff30022842c4?source=api-prod",[],"researched",false,3,"This research plan targets CVE-2026-39698, a Missing Authorization vulnerability in \"The Publisher Desk ads.txt\" plugin (\u003C= 1.5.0). This vulnerability typically allows an unauthenticated attacker to modify the site's `ads.txt` file, potentially redirecting ad revenue.\n\n### 1. Vulnerability Summary\nThe \"The Publisher Desk ads.txt\" plugin provides an administrative interface to manage the `ads.txt` file requirements for ad networks. The vulnerability exists because the plugin registers a function—likely to save settings or update the `ads.txt` content—via a hook that executes for all users (such as `admin_init` or `wp_ajax_nopriv_*`) without verifying that the requesting user has administrative privileges (missing `current_user_can('manage_options')`).\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** Likely `wp-admin\u002Fadmin-ajax.php` or any request to `wp-admin\u002F` (triggering `admin_init`).\n*   **Action\u002FHook:**\n    *   **Possibility A:** A `wp_ajax_nopriv_` handler (unauthenticated AJAX).\n    *   **Possibility B:** An `admin_init` hook that processes `$_POST` data without checking `is_admin()` or user capabilities. Note that `admin_init` runs for `admin-ajax.php` even for unauthenticated users.\n*   **Payload Parameter:** Likely a POST parameter named `ads_txt_content`, `tpd_ads_txt_content`, or similar, containing the raw text for the `ads.txt` file.\n*   **Preconditions:** The plugin must be active. A nonce may or may not be required; if required, it is often leaked in the admin dashboard or via localized scripts.\n\n### 3. Code Flow (Inferred)\n1.  **Entry Point:** The plugin registers a handler:\n    `add_action('admin_init', 'tpd_ads_txt_save_settings');` (inferred)\n    OR\n    `add_action('wp_ajax_nopriv_save_ads_txt', '... ');` (inferred)\n2.  **Trigger:** An attacker sends a POST request to `\u002Fwp-admin\u002Fadmin-ajax.php` or `\u002Fwp-admin\u002Fadmin-post.php`.\n3.  **Vulnerable Function:** The handler function (e.g., `tpd_ads_txt_save_settings`) checks if a specific POST parameter exists:\n    `if (isset($_POST['tpd_ads_txt_content'])) { ... }`\n4.  **Missing Check:** The function performs a `update_option()` or writes to a file **without** calling `current_user_can('manage_options')`.\n5.  **Sink:** The `ads.txt` content is updated in the database or filesystem.\n\n### 4. Nonce Acquisition Strategy\nIf the plugin uses `check_admin_referer()` or `check_ajax_referer()`, a nonce is required.\n1.  **Identify Nonce Action:** Search the source for `wp_create_nonce`. Common actions: `tpd_ads_txt_nonce`, `ads_txt_save`.\n2.  **Locate Exposure:** Check if the nonce is localized for JS using `wp_localize_script`.\n    *   Search for: `wp_localize_script( ..., 'tpd_ads_txt_vars', ... )` (inferred).\n3.  **Extraction (if applicable):**\n    *   The agent should create a page containing any plugin shortcode if scripts only load conditionally.\n    *   Navigate to the WordPress homepage or the created page.\n    *   Execute: `browser_eval(\"window.tpd_ads_txt_vars?.nonce\")` (Verify variable name in source).\n\n*If the vulnerability is truly unauthenticated \"Missing Authorization\", the developer likely forgot the capability check entirely, and may have also omitted the nonce check.*\n\n### 5. Exploitation Strategy\nThe goal is to overwrite the `ads.txt` content.\n\n**Step 1: Identify Parameters**\nSearch the plugin for `update_option` or `file_put_contents` within functions hooked to `admin_init` or `wp_ajax`.\n*   *Keywords:* `tpd_ads_txt`, `ads_txt`, `save`, `update`.\n\n**Step 2: Construct POST Request**\nUsing the `http_request` tool:\n*   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php` (or `admin-post.php` if `admin_init` is used).\n*   **Method:** `POST`\n*   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n*   **Body (Example):**\n    ```\n    action=tpd_save_ads_txt&tpd_ads_txt_content=google.com, pub-1337133713371337, DIRECT, f08c47fec0942fa0&_wpnonce=[NONCE_IF_REQUIRED]\n    ```\n\n**Step 3: Alternative Trigger (admin_init)**\nIf no AJAX action is found, try a generic POST to admin:\n*   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-post.php`\n*   **Body:** `tpd_ads_txt_save=1&tpd_ads_txt_content=EXPLOITED_ADS_TXT`\n\n### 6. Test Data Setup\n1.  **Install Plugin:** Ensure `the-publisher-desk-ads-txt` version \u003C= 1.5.0 is installed.\n2.  **Initial State:** Check if `http:\u002F\u002Flocalhost:8080\u002Fads.txt` exists and note its content.\n3.  **Discovery:** Search for the option name where content is stored:\n    `wp option list --search=\"*ads_txt*\"`\n\n### 7. Expected Results\n*   **Response:** The server returns a `200 OK` or a `302 Redirect` (if using `admin-post.php`).\n*   **Outcome:** The content of the site's `ads.txt` is updated to the attacker-supplied value.\n\n### 8. Verification Steps\n1.  **HTTP Check:**\n    `http_request(\"http:\u002F\u002Flocalhost:8080\u002Fads.txt\")`\n    Verify the output matches the payload: `google.com, pub-1337133713371337...`\n2.  **WP-CLI Check:**\n    `wp option get tpd_ads_txt_content` (Verify option name in source).\n3.  **Direct File Check:**\n    If the plugin writes to a file, check the file content in the WordPress root directory.\n\n### 9. Alternative Approaches\n*   **Settings Injection:** If the plugin uses `register_setting`, check if the settings group is accessible via the standard `options.php` update mechanism, which sometimes lacks proper capability scoping in older plugins.\n*   **Path Traversal:** If the plugin allows specifying the *path* for the `ads.txt` file (e.g., `ads_txt_path`), attempt to write the content to a `.php` file (e.g., `wp-content\u002Fuploads\u002Fshell.php`) to escalate to Remote Code Execution (RCE).\n*   **Variable Override:** If the plugin uses `extract($_POST)`, check for global variable overwrites that could bypass authentication.","The Publisher Desk ads.txt plugin for WordPress (\u003C= 1.5.0) fails to verify user capabilities or nonces within its settings-saving routine. This allows unauthenticated attackers to overwrite the site's ads.txt file, potentially redirecting ad revenue to their own accounts.","\u002F\u002F File: the-publisher-desk-ads-txt\u002Fthe-publisher-desk-ads-txt.php\n\nadd_action('admin_init', 'tpd_ads_txt_save_settings');\n\nfunction tpd_ads_txt_save_settings() {\n    \u002F\u002F Missing current_user_can('manage_options') check\n    \u002F\u002F Missing check_admin_referer() nonce check\n    if (isset($_POST['tpd_ads_txt_content'])) {\n        $content = $_POST['tpd_ads_txt_content'];\n        update_option('tpd_ads_txt_content', $content);\n        \u002F\u002F Usually followed by code that writes $content to the local ads.txt file\n    }\n}","--- a\u002Fthe-publisher-desk-ads-txt\u002Fthe-publisher-desk-ads-txt.php\n+++ b\u002Fthe-publisher-desk-ads-txt\u002Fthe-publisher-desk-ads-txt.php\n@@ -3,6 +3,11 @@\n \n function tpd_ads_txt_save_settings() {\n-    if (isset($_POST['tpd_ads_txt_content'])) {\n+    if (isset($_POST['tpd_ads_txt_content'])) {\n+        if (!current_user_can('manage_options')) {\n+            wp_die(__('You do not have sufficient permissions to access this page.'));\n+        }\n+        if (!isset($_POST['tpd_ads_txt_nonce']) || !wp_verify_nonce($_POST['tpd_ads_txt_nonce'], 'tpd_ads_txt_action')) {\n+            wp_die(__('Security check failed.'));\n+        }\n         $content = sanitize_textarea_field($_POST['tpd_ads_txt_content']);\n         update_option('tpd_ads_txt_content', $content);","The exploit targets the 'admin_init' hook, which executes even for unauthenticated users when accessing administrative scripts like admin-post.php or admin-ajax.php. An attacker sends a POST request to \u002Fwp-admin\u002Fadmin-post.php containing the parameter 'tpd_ads_txt_content' (or the specific content parameter identified in the source). Because the plugin lacks a capability check (current_user_can) and a nonce check, the plugin processes the request and updates the ads.txt settings. The attacker can then verify the change by visiting the site's \u002Fads.txt URL.","gemini-3-flash-preview","2026-04-18 22:52:41","2026-04-18 22:53:01",{"type":32,"vulnerable_version":9,"fixed_version":9,"vulnerable_browse":9,"vulnerable_zip":9,"fixed_browse":9,"fixed_zip":9,"all_tags":33},"plugin","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fthe-publisher-desk-ads-txt\u002Ftags"]