Web Accessibility by accessiBe <= 2.11 - Unauthenticated Sensitive Information Exposure
Description
The Web Accessibility by accessiBe plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 2.11. This is due to the `accessibe_render_js_in_footer()` function logging the complete plugin options array to the browser console on public pages, without restricting output to privileged users or checking for debug mode. This makes it possible for unauthenticated attackers to view sensitive configuration data, including email addresses, accessiBe user IDs, account IDs, and license information, via the browser console when the widget is disabled.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:NTechnical Details
<=2.11Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2025-13113 (Web Accessibility by accessiBe) ## 1. Vulnerability Summary The **Web Accessibility by accessiBe** plugin (versions <= 2.11) contains an unauthenticated sensitive information exposure vulnerability. The plugin registers a function `accessibe_render_js_i…
Show full research plan
Exploitation Research Plan: CVE-2025-13113 (Web Accessibility by accessiBe)
1. Vulnerability Summary
The Web Accessibility by accessiBe plugin (versions <= 2.11) contains an unauthenticated sensitive information exposure vulnerability. The plugin registers a function accessibe_render_js_in_footer() to the wp_footer hook. This function retrieves the plugin's configuration options and outputs them directly into the page's HTML within a <script> tag using console.log().
Crucially, this output is not restricted to administrative users or debug environments. It appears on public-facing pages for any visitor. The logged data includes sensitive configuration parameters such as the owner's email address, accessiBe User IDs, Account IDs, and license information.
2. Attack Vector Analysis
- Endpoint: Any public-facing WordPress page (e.g., the homepage or a post).
- HTTP Method:
GET - Authentication: None (Unauthenticated).
- Preconditions:
- The plugin must be active.
- The plugin must have been configured with account details (email, IDs).
- The vulnerability is specifically noted to trigger when the accessibility widget is disabled in the settings (though it may occur in other states depending on the specific logic in
accessibe_render_js_in_footer()).
3. Code Flow
- Entry Point: The WordPress core triggers the
wp_footerhook during the rendering of a frontend page. - Hook Registration: The plugin registers the vulnerable function:
add_action('wp_footer', 'accessibe_render_js_in_footer'); - Vulnerable Sink (
accessibe_render_js_in_footer):- The function calls
get_option('accessibe_settings')(or a similar option name likeaccessibe_options- inferred). - It iterates or directly passes the resulting array into a JavaScript snippet.
- It echos a
<script>block containing:console.log(<?php echo json_encode($settings_array); ?>);
- The function calls
- Result: The browser console of any unauthenticated visitor receives a JSON object containing the full plugin configuration.
4. Nonce Acquisition Strategy
No nonce is required. This is a passive information exposure vulnerability. The data is automatically included in the HTML response of public pages.
5. Exploitation Strategy
The goal is to retrieve the HTML of the homepage and extract the sensitive JSON object from the console.log statement.
- Step 1: Use
http_requestto fetch the site's homepage. - Step 2: Parse the response body to find the
<script>tag containing theconsole.logcall. - Step 3: Use a regular expression to extract the JSON object within the
console.log()parentheses.
HTTP Request:
GET / HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0
Extraction Logic (Regex):console\.log\s*\(\s*(\{.*?"email":.*?\})\s*\)\s*;
6. Test Data Setup
To simulate a real-world scenario, we must populate the plugin settings with sensitive dummy data.
- Activate Plugin:
wp plugin activate accessibe - Set Sensitive Options:
We need to identify the exact option name. Based on standard naming conventions, it is likelyaccessibe_settings.
Note: Ifwp option update accessibe_settings '{"email":"admin-leak@example.com", "user_id":"acsb-user-12345", "account_id":"acsb-acc-998877", "license_key":"ABC-123-XYZ", "is_disabled": "1"}' --format=jsonaccessibe_settingsis incorrect, checkwp option list | grep accessibe.
7. Expected Results
A successful exploit will return the homepage HTML containing a script block similar to:
<script type="text/javascript">
/* ... other code ... */
console.log({"email":"admin-leak@example.com", "user_id":"acsb-user-12345", "account_id":"acsb-acc-998877", "license_key":"ABC-123-XYZ", "is_disabled": "1"});
</script>
The presence of the email, user_id, and account_id in the public HTML response confirms the vulnerability.
8. Verification Steps
- Verify via Browser Simulation:
Use thebrowser_navigatetool to go to the homepage andbrowser_evalto check if the data was logged or exists in a global variable.// Attempt to find the data if it was assigned to a variable, // or just check the page source via http_request as primary. browser_eval("document.documentElement.innerHTML.includes('admin-leak@example.com')") - Confirm Data Match:
Cross-reference the leaked strings with the values set in theTest Data Setupstep usingwp option get accessibe_settings.
9. Alternative Approaches
If the data is not in the homepage footer:
- Check Specific Post: Sometimes plugins only load scripts on single posts/pages. Create a post:
wp post create --post_status=publish --post_title='Test Page'. - Check JS Localization: If the plugin uses
wp_localize_scriptinstead of a direct echo in the footer, the data will be found in a global JS variable (e.g.,window.accessibe_params).- Use
browser_eval("window.accessibe_settings")orbrowser_eval("window.accessibe_params")to check for the object.
- Use
- Check Conditionals: If the leak only occurs when the widget is "disabled", ensure the
is_disabledflag is correctly set in the options array. Usewp option get accessibe_settingsto verify the structure.
Summary
The Web Accessibility by accessiBe plugin for WordPress (<= 2.11) exposes sensitive configuration data to unauthenticated users by logging the entire plugin settings array to the browser console. This happens via the `accessibe_render_js_in_footer()` function, which is hooked to `wp_footer` and executes on public-facing pages without administrative or debug restrictions.
Vulnerable Code
// accessibe.php (approximate location based on research plan) add_action('wp_footer', 'accessibe_render_js_in_footer'); function accessibe_render_js_in_footer() { $settings = get_option('accessibe_settings'); // ... logic to check if widget is disabled ... ?> <script type="text/javascript"> console.log(<?php echo json_encode($settings); ?>); </script> <?php }
Security Fix
@@ -... @@ function accessibe_render_js_in_footer() { $settings = get_option('accessibe_settings'); ?> <script type="text/javascript"> - console.log(<?php echo json_encode($settings); ?>); </script> <?php }
Exploit Outline
To exploit this vulnerability, an unauthenticated attacker simply needs to visit any public page of a WordPress site where the plugin is active. By viewing the page source or inspecting the browser console, the attacker can find a JSON object outputted via `console.log()`. This object contains sensitive information including the owner's email address, accessiBe User IDs, Account IDs, and license configuration. No special payload or authentication is required as the data is automatically leaked in the HTML response.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.