Pricing Tables for WP <= 1.1.0 - Reflected Cross-Site Scripting via 'page' Parameter
Description
The Pricing Tables for WP plugin for WordPress is vulnerable to Reflected Cross-Site Scripting via the 'page' parameter in all versions up to, and including, 1.1.0. This is due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that execute if they can successfully trick an administrator into performing an action such as clicking on a link.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:NTechnical Details
<=1.1.0I cannot fulfill this request. I am prohibited from generating actionable exploitation plans, functional payloads, or instructions for performing attacks on specific software or endpoints, as these could be used to facilitate real-world harm. However, I can provide a technical analysis of how refle…
Show full research plan
I cannot fulfill this request. I am prohibited from generating actionable exploitation plans, functional payloads, or instructions for performing attacks on specific software or endpoints, as these could be used to facilitate real-world harm.
However, I can provide a technical analysis of how reflected cross-site scripting (XSS) typically occurs in WordPress plugins and how researchers and developers can identify and remediate these vulnerabilities.
Technical Analysis: Reflected XSS in WordPress page Parameter
Reflected XSS in WordPress often centers on the way the application handles administrative routing and user-controlled input in the backend dashboard.
1. Vulnerability Mechanism
In WordPress, the page parameter is a reserved query variable used to determine which administrative menu or submenu page should be loaded (e.g., /wp-admin/admin.php?page=plugin-settings).
A vulnerability typically arises when a plugin:
- Registers a custom admin page using
add_menu_page()oradd_submenu_page(). - Accesses the
pageparameter directly from the$_GETor$_REQUESTsuperglobals within the callback function or during script localization. - Echoes this value back into the HTML document without applying context-aware escaping functions (such as
esc_attr()oresc_html()).
2. Theoretical Code Flow
The vulnerability often follows this path:
- Source: The application receives user input via the
pageURL parameter. - Processing: The plugin identifies its registered slug but may also extract the raw value of
$_GET['page']to perform dynamic rendering, such as populating hidden form fields or generating breadcrumbs. - Sink: The unvalidated input is outputted directly to the browser. For example:
If an attacker provides a value like// Vulnerable Example echo '<input type="hidden" name="page" value="' . $_GET['page'] . '">';my-plugin"><script>alert(1)</script>, the resulting HTML becomes:<input type="hidden" name="page" value="my-plugin"><script>alert(1)</script>">
3. Security Research Methodology
When auditing for reflected XSS in this context, researchers typically look for:
- Lack of Escaping: Identifying instances where
echo,print, orprintfare used on global input variables without wrapping them in WordPress escaping functions. - Localization Vulnerabilities: Checking
wp_localize_script()calls where thepageparameter is included in the data array, which can lead to DOM-based XSS if the JavaScript processes that data unsafely. - Admin Context: Since these vulnerabilities often require an active administrative session, they are frequently used in CSRF chains where an administrator is tricked into clicking a malicious link.
4. Remediation Best Practices
To prevent reflected XSS, developers must follow the principle of "escaping on output" using the appropriate function for the HTML context:
- HTML Attributes: Use
esc_attr()when placing input inside an attribute.echo '<input type="hidden" name="page" value="' . esc_attr( $_GET['page'] ) . '">'; - HTML Content: Use
esc_html()for text nodes between tags. - URLs: Use
esc_url()for attributes likehreforsrc. - JSON/JavaScript: Use
wp_json_encode()oresc_js()when passing data to scripts.
Furthermore, implementing strict Capability Checks (current_user_can()) and Nonce Verification (check_admin_referer()) ensures that only authorized users can interact with sensitive administrative functionality, reducing the overall attack surface.
For further learning on WordPress security, you may consult the WordPress Plugin Handbook on Security or resources like the OWASP XSS Prevention Cheat Sheet.
Summary
The Pricing Tables for WP plugin is vulnerable to reflected cross-site scripting because it echoes the 'page' query parameter in the WordPress administrative dashboard without sufficient sanitization or output escaping. An attacker can exploit this by tricking a logged-in administrator into clicking a crafted link containing a malicious payload in the 'page' parameter, leading to script execution in the administrator's browser session.
Vulnerable Code
// File: awesome-pricing-tables-lite-by-optimalplugins/admin/views/pricing-tables.php (inferred) // The plugin echoes the page parameter directly from the GET superglobal into a hidden input field or HTML attribute. <form action="" method="post"> <input type="hidden" name="page" value="<?php echo $_GET['page']; ?>"> <!-- ... rest of the form ... --> </form>
Security Fix
@@ -10,1 +10,1 @@ - <input type="hidden" name="page" value="<?php echo $_GET['page']; ?>"> + <input type="hidden" name="page" value="<?php echo esc_attr($_GET['page']); ?>">
Exploit Outline
The exploit targets an authenticated administrator of the WordPress site. 1. **Payload Construction**: The attacker crafts a malicious URL where the 'page' parameter contains an HTML-breaking payload and a script tag. For example: `wp-admin/admin.php?page=pricing-table-slug"><script>alert(document.cookie)</script>`. 2. **Delivery**: The attacker uses social engineering (phishing, forum links, or private messages) to trick a site administrator into visiting this URL while they are logged into the WordPress dashboard. 3. **Reflected Execution**: When the administrator visits the link, the plugin processes the request and echoes the raw 'page' parameter value into the HTML of the settings page. Because the input is not escaped with `esc_attr()`, the browser interprets the attacker's input as valid HTML/JavaScript tags. 4. **Outcome**: The injected script executes in the context of the administrator's session, potentially allowing the attacker to perform administrative actions, steal session cookies, or inject further backdoors into the WordPress site.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.