CSRF to XSS Vulnerability In WordPress Plugin with 50,000 Installs

CSRF to XSS Vulnerability In WordPress Plugin with 50,000 Installs

When auditing a WordPress site recently, I found a vulnerability in a popular plugin that highlights a common security pitfall, forgetting to protect admin-side form actions with nonces. On the surface, the plugin was working as intended allowing administrators to create popup content with custom HTML. But because of missing CSRF protections, that benign functionality could be weaponized into a serious stored XSS attack.

If your running wordpress and wondering the best way to protect against these style of attacks read my post on protecting wordpress sites from hackers.

It important to note this vulnerability would be mitigated by a good wordpress firewall such as wordfence.

The Vulnerable Plugin / Request

The popup box plugin version <= 5.4.9 by Ays-Pro was the plugin in question – https://en-gb.wordpress.org/plugins/ays-popup-box/ which has now been patched and is awaiting a CVE.

The plugin exposed an administrative action for creating popups at:

POST /wp-admin/admin.php?page=ays-pb&action=add

This handler accepts parameters containing HTML, without verifying that the request originated from the web server itself. This could allow an attacker to inject malicious code into a popup on the front end and or the backend.

Why This Matters

In WordPress, administrators are normally trusted to enter arbitrary HTML (and sometimes even JavaScript). That’s by design power users need flexibility.

But without CSRF protections, an attacker can trick an authenticated administrator into unintentionally submitting this request (for example, by visiting a malicious page). If that happens, the attacker can cause the admin’s browser to create a new popup containing attacker-controlled code.

An attacker can craft a malicious webpage that triggers a request to inject a popup into the WordPress admin panel. Since the server does not validate the request’s origin (referrer) and the action lacks a WordPress nonce, it is vulnerable to CSRF. If an administrator is tricked into visiting the page such as through a phishing campaign the malicious code will be executed, compromising the admin interface.

Because popup content is displayed both on the frontend (to site visitors) and in the backend (to admins managing content), this becomes a stored XSS issue:

– Site visitors could be served malicious JavaScript.
– The administrator’s own backend session could be hijacked.
– Session cookies, CSRF tokens, and other sensitive data could be stolen.

The result: a simple missing nonce and lack of protection on the refferer header could escalate into site-wide compromise.

Back-end injection effecting Admin interface.

 

Front-end injection effecting users.

 

 

Root Cause: Missing CSRF Protection

WordPress has built-in mechanisms to prevent this exact class of vulnerability. Sensitive admin actions should always:

1. Require a **nonce** in the form.
2. Validate that nonce (and the referer) when processing the request.
3. Enforce **capability checks** (e.g. `current_user_can(‘manage_options’)`).
4. Only allow **POST** for state-changing actions.

In this plugin’s case, none of these checks were present.

Remediation

Here’s how to secure the vulnerable `action=add` handler:

Add a nonce field to the form

Verify the nonce and referrer on submit:

if ( ! check_admin_referer( 'function, 'wp_nonce' ) ) {
wp_die( 'Invalid request.' );
} 

This ensures the request originated from a valid WordPress form and that it matches the expected admin URL.

Add capability and method checks:

if ( $_SERVER['REQUEST_METHOD'] !== 'POST' ) {
wp_die( 'Invalid request method.' );
}
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( 'Insufficient permissions.' );
}

Key Takeaway

Unprotected POST requests to privileged endpoints can lead to CSRF vulnerabilities. Without proper verification such as WordPress nonces malicious sites can silently trigger administrative actions if an authenticated user is tricked into visiting them. In this case malicious code can be injected both into the victims admin panel and front end interface.

If you’re a WordPress plugin developer, remember:

Always add nonces to admin forms.

Always check them with check_admin_referer() when processing.

Without CSRF protection attackers can flip the intent of normal features into exploits.

If your interested in having your web application or wordpress plugin checked for security vulnerabilities please checkout our Web Application Penetration Testing service.