[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fJItZv7KbMQ2PcZz32CFlEIQCXHHJyWsNGc7kipJ9tMc":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-4025","privatecontent-free-authenticated-contributor-stored-cross-site-scripting-via-align-shortcode-attribute","PrivateContent Free \u003C= 1.2.0 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'align' Shortcode Attribute","The PrivateContent Free plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'align' shortcode attribute in the [pc-login-form] shortcode in all versions up to, and including, 1.2.0. This is due to insufficient input sanitization and output escaping on the 'align' attribute. Specifically, the attribute value flows from the shortcode through pc_login_form() to pc_static::form_align(), where it is directly concatenated into an HTML class attribute without esc_attr() or any escaping. This makes it possible for authenticated attackers, with Contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.","privatecontent-free",null,"\u003C=1.2.0","1.3.0","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-04-07 21:05:38","2026-04-08 09:25:49",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fa9ed2943-e108-49e3-ba16-f74ce3136bde?source=api-prod",1,[22,23,24,25,26,27,28,29],"builders_integration\u002Fguten_elements\u002Flogin\u002Flogin.js","builders_integration\u002Fguten_elements\u002Flogin\u002Flogin.php","builders_integration\u002Fguten_elements\u002Flogout\u002Flogout.js","builders_integration\u002Fguten_elements\u002Flogout\u002Flogout.php","builders_integration\u002Fguten_elements\u002Fregistr\u002Fregistr.js","builders_integration\u002Fguten_elements\u002Fregistr\u002Fregistr.php","builders_integration\u002Fguten_elements\u002Fuser_del\u002Fuser_del.js","builders_integration\u002Fguten_elements\u002Fuser_del\u002Fuser_del.php","researched",false,3,"# Research Plan: CVE-2026-4025 - PrivateContent Free Stored XSS\n\n## 1. Vulnerability Summary\nThe **PrivateContent Free** plugin (up to 1.2.0) contains a stored cross-site scripting (XSS) vulnerability. The plugin fails to sanitize or escape the `align` attribute within the `[pc-login-form]` shortcode (and likely other related shortcodes). This value is passed to `pc_static::form_align()` and concatenated directly into an HTML class attribute without using `esc_attr()`. Authenticated users with **Contributor** level access or higher can inject malicious JavaScript into pages, which will execute when any user (including administrators) views that page.\n\n## 2. Attack Vector Analysis\n- **Endpoint\u002FShortcode:** `[pc-login-form]` (also check `[pc-registration-form]` and `[pc-user-del-box]`).\n- **Vulnerable Parameter:** The `align` attribute within the shortcode.\n- **Authentication Level:** Contributor+ (any role allowed to create or edit posts and use shortcodes).\n- **Preconditions:** The plugin must be active, and a post containing the malicious shortcode must be published or previewed.\n\n## 3. Code Flow\nBased on the vulnerability description and provided source files:\n1. **Entry Point:** A user with Contributor permissions creates a post with the shortcode `[pc-login-form align='PAYLOAD']`.\n2. **Shortcode Handling:** WordPress parses the shortcode and calls the handler function (inferred as `pc_login_form()` or the `render_callback` defined in Gutenberg integration like `pvtcont_login_guten_handler`).\n3. **Data Processing:** The `align` attribute value is extracted from the `$atts` array.\n4. **Vulnerable Sink:** The value is passed to `pc_static::form_align()`.\n5. **Output Generation:** Inside `pc_static::form_align()`, the code likely performs a concatenation similar to:\n   ```php\n   \u002F\u002F Inferred vulnerable code in pc_static::form_align()\n   return 'pc_form_' . $align_attr; \n   ```\n   This returned string is then placed into a template:\n   ```php\n   \u002F\u002F Inferred output context\n   echo '\u003Cdiv class=\"' . pc_static::form_align($atts['align']) . '\">';\n   ```\n6. **Result:** The lack of `esc_attr()` allows an attacker to break out of the `class` attribute and inject event handlers (e.g., `onmouseover`, `autofocus onfocus`).\n\n## 4. Nonce Acquisition Strategy\nShortcodes in WordPress do not require nonces for rendering. They are processed on the server whenever a post is rendered for display. Therefore, **no nonce is required** for the core exploitation of this vulnerability.\n\nHowever, if the PoC involves using the Gutenberg editor via the REST API to save the post, a standard WordPress REST API nonce (`_wpnonce`) would be required. This can be obtained by:\n1. Navigating to the post editor page (`\u002Fwp-admin\u002Fpost-new.php`).\n2. Extracting the `wpApiSettings.nonce` from the page source using `browser_eval`.\n\n## 5. Exploitation Strategy\nThe goal is to demonstrate that a Contributor user can inject a script that executes when viewed.\n\n### Step 1: Create a Post with Payload\nUsing the `http_request` tool, the agent will authenticate as a Contributor and create a post containing the malicious shortcode.\n\n- **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fpost-new.php` (to initiate) or using `wp-cli` to create the post directly.\n- **Shortcode Payload:** `[pc-login-form align=' \" onmouseover=\"alert(document.domain)\" style=\"padding:100px;border:1px solid red;\" ']`\n  - *Note:* We use `style` to make the element large and easy to trigger the `onmouseover` event.\n\n### Step 2: View the Post\nThe agent will navigate to the newly created post's permalink using `http_request`.\n\n### Step 3: Analyze Response\nSearch the response body for the injected payload to confirm it rendered without escaping.\n- **Target String:** `class=\"pc_login_form  \" onmouseover=\"alert(document.domain)\"`\n\n## 6. Test Data Setup\n1. **Plugin:** Ensure `privatecontent-free` version 1.2.0 is installed and active.\n2. **User:** Create a user with the **Contributor** role.\n   ```bash\n   wp user create attacker attacker@example.com --role=contributor --user_pass=password123\n   ```\n3. **Post Content:** Use the following content for the post:\n   ```text\n   Check out this login form:\n   [pc-login-form align=' \" onmouseover=\"alert(document.domain)\" ']\n   ```\n\n## 7. Expected Results\n- The HTTP response from the published page should contain the raw, unescaped payload within the class attribute of a `div` or `form` element.\n- Specifically, the HTML output should look like:\n  `\u003Cdiv class=\"pc_login_form  \" onmouseover=\"alert(document.domain)\" ...`\n- The `\"` character in the `align` attribute will close the `class` attribute value, allowing the `onmouseover` attribute to be injected as a separate HTML attribute.\n\n## 8. Verification Steps\n1. **HTML Inspection:** After the `http_request` to the post, use `grep` or string matching on the output:\n   ```bash\n   # Confirm the injection\n   grep -P 'class=\"[^\"]*\"\\s+onmouseover=\"alert'\n   ```\n2. **Database Check:** Verify the shortcode was stored correctly via `wp-cli`:\n   ```bash\n   wp post get \u003CPOST_ID> --field=post_content\n   ```\n\n## 9. Alternative Approaches\nIf `[pc-login-form]` is patched or blocked, try the other Gutenberg-integrated elements found in the source:\n1. **Registration Form:** `[pc-registration-form align=' \" onmouseover=\"alert(1)\" ']` (linked to `builders_integration\u002Fguten_elements\u002Fregistr\u002Fregistr.php`)\n2. **User Deletion Box:** `[pc-user-del-box align=' \" onmouseover=\"alert(1)\" ']` (linked to `builders_integration\u002Fguten_elements\u002Fuser_del\u002Fuser_del.php`)\n\nBoth of these use the `pc_align` \u002F `align` attribute pattern and are registered with similar render handlers that likely share the vulnerable `pc_static::form_align()` function.","The PrivateContent Free plugin for WordPress (up to version 1.2.0) is vulnerable to Stored Cross-Site Scripting due to insufficient input sanitization and output escaping on the 'align' attribute in shortcodes such as [pc-login-form]. An authenticated attacker with Contributor-level access or higher can inject arbitrary JavaScript by breaking out of the HTML class attribute context where the value is concatenated in pc_static::form_align().","\u002F\u002F builders_integration\u002Fguten_elements\u002Flogin\u002Flogin.php @ 1.2.0\n'pc_align' => array(\n\t'label'\t\t=> esc_html__('Form alignment', 'privatecontent-free'),\n\t'type'\t\t=> 'select',\n\t'opts'\t\t=> array(\n\t\t'center'\t=> esc_html__('Center', 'privatecontent-free'),\n\t\t'left'\t\t=> esc_html__('Left', 'privatecontent-free'),\n\t\t'right'\t\t=> esc_html__('Right', 'privatecontent-free'),\n\t),\n\t'default' \t=> 'center',\n\t'panel'\t\t=> 'main',\n),\n\n---\n\n\u002F\u002F builders_integration\u002Fguten_elements\u002Fregistr\u002Fregistr.php @ 1.2.0\n'pc_align' => array(\n\t'label'\t\t=> esc_html__('Form alignment', 'privatecontent-free'),\n\t'type'\t\t=> 'select',\n\t'opts'\t\t=> array(\n\t\t'center'\t=> esc_html__('Center', 'privatecontent-free'),\n\t\t'left'\t\t=> esc_html__('Left', 'privatecontent-free'),\n\t\t'right'\t\t=> esc_html__('Right', 'privatecontent-free'),\n\t),\n\t'default' \t=> 'center',\n\t'panel'\t\t=> 'main',\n),","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fprivatecontent-free\u002F1.2.0\u002Fbuilders_integration\u002Fguten_elements\u002Flogin\u002Flogin.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fprivatecontent-free\u002F1.3.0\u002Fbuilders_integration\u002Fguten_elements\u002Flogin\u002Flogin.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fprivatecontent-free\u002F1.2.0\u002Fbuilders_integration\u002Fguten_elements\u002Flogin\u002Flogin.php\t2026-01-20 10:38:14.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fprivatecontent-free\u002F1.3.0\u002Fbuilders_integration\u002Fguten_elements\u002Flogin\u002Flogin.php\t2026-04-02 10:00:16.000000000 +0000\n@@ -13,12 +13,12 @@\n \t\t'panel'\t\t=> 'main',\n \t),\n \t'pc_align' => array(\n-\t\t'label'\t\t=> esc_html__('Form alignment', 'privatecontent-free'),\n+\t\t'label'\t\t=> esc_html__('Form alignment', 'pc_ml'),\n \t\t'type'\t\t=> 'select',\n \t\t'opts'\t\t=> array(\n-\t\t\t'center'\t=> esc_html__('Center', 'privatecontent-free'),\n-\t\t\t'left'\t\t=> esc_html__('Left', 'privatecontent-free'),\n-\t\t\t'right'\t\t=> esc_html__('Right', 'privatecontent-free'),\n+\t\t\t'center'\t=> esc_html__('Center', 'pc_ml'),\n+\t\t\t'left'\t\t=> esc_html__('Left', 'pc_ml'),\n+\t\t\t'right'\t\t=> esc_html__('Right', 'pc_ml'),\n \t\t),\n \t\t'default' \t=> 'center',\n \t\t'panel'\t\t=> 'main', (truncated)","1. Log in to the WordPress site as a user with Contributor-level permissions (or higher).\n2. Create a new post or edit an existing one.\n3. Insert a shortcode for a PrivateContent form (e.g., [pc-login-form]) and provide a malicious payload for the 'align' attribute, such as: [pc-login-form align=' \" onmouseover=\"alert(document.domain)\" '].\n4. Publish the post.\n5. View the post as any user (including an Administrator). The double-quote in the payload will close the intended class attribute, allowing the onmouseover event handler to be injected as a new attribute on the form container element. The script executes when a user hovers over the form.","gemini-3-flash-preview","2026-04-17 20:24:55","2026-04-17 20:25:12",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","1.2.0","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fprivatecontent-free\u002Ftags\u002F1.2.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fprivatecontent-free.1.2.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fprivatecontent-free\u002Ftags\u002F1.3.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fprivatecontent-free.1.3.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fprivatecontent-free\u002Ftags"]