The WordPress Plugin and Theme Editor Must Go

WordPress Vulnerability

…or “How WordPress Gets Hacked”

The prelude

With so many reports of WordPress sites being hacked in one way or another, I decided to see how exactly WordPress sites are being invaded. The WordPress Codex has an excellent FAQ section titled “My site was hacked“, and it’s great. Hardening WordPress is another fantastic entry that deserves even more attention.

Not so long ago, I setup a honeypot on one of my private servers. I grabbed the latest stable version of WordPress and installed it. Waiting for any new WordPress vulnerability to be exploited would not be viable (although the TimThumb vulnerability is occasionally being attempted). I considered the latest stable version of WordPress secure, correctly setup, so I chose the single weakest link in the chain, located between the chair and the screen – the Admin.

Thus, the most practical point of entry was set to be the login screen, with a simple username and password set – admin:admin. Simple enough. The hardest part was to get the site indexed so that malicious bots would start knocking at my door. I set up a simple content spinner to get things going (sorry, Google).

About two weeks later the first attackers joined the crawler party. A fair share of automated commenting, some automated vulnerability scans, both specific to WordPress and not, and of course wp-login.php bruteforcing. Eventually something did get in. Here’s what it did:

15623-##########.ru:80 host-41.215.241.146.citynethost.com - - [16/Feb/2012:16:16:39 +0500] "POST /wp-login.php HTTP/1.0" 302 932 "-" "Mozilla/4.0 (compatible; Synapse)"
15625:##########.ru:80 host-41.215.241.146.citynethost.com - - [16/Feb/2012:16:16:42 +0500] "GET /wp-admin/theme-editor.php?file=/themes/twentyten/404.php&theme=Twenty+Ten&dir=theme HTTP/1.0" 200 28115 "-" "Mozilla/4.0 (compatible; Synapse)"
15626-##########.ru:80 host-41.215.241.146.citynethost.com - - [16/Feb/2012:16:16:45 +0500] "POST /wp-admin/theme-editor.php HTTP/1.0" 302 598 "-" "Mozilla/4.0 (compatible; Synapse)"
15627:##########.ru:80 host-41.215.241.146.citynethost.com - - [16/Feb/2012:16:16:48 +0500] "POST /wp-content/themes/twentyten/404.php HTTP/1.0" 200 539 "-" "Mozilla/4.0 (compatible; Synapse)"
15629:##########.ru:80 host-41.215.241.146.citynethost.com - - [16/Feb/2012:16:16:49 +0500] "POST /wp-content/themes/twentyten/404.php HTTP/1.0" 200 539 "-" "Mozilla/4.0 (compatible; Synapse)"
15630-##########.ru:80 host-41.215.241.146.citynethost.com - - [16/Feb/2012:16:16:52 +0500] "POST /wp-admin/theme-editor.php HTTP/1.0" 302 598 "-" "Mozilla/4.0 (compatible; Synapse)"

An unexpected turn of events

This was quite unexpected. I completely forgot about the fact that WordPress had built-in Theme and Plugin Editors stashed away in the Plugin and Appearance menus. Last time I used one was at least 4 years ago, and even then it didn’t work.

And it didn’t work because it requires PHP to be able to write to the editable files, so permissions would have to probably be set. Unless PHP is almighty for the files the editors are useless. Changes can’t be made, and that’s great, right? I think so.

A lose-lose situation

In most correct (you’re-doing-it-right) setups, site administrators wouldn’t have specifically set permissions for PHP to write to any of the wp-content files, and the files wouldn’t belong to a user or group that PHP belongs to. So the WordPress built-in Editors are of no practical use.

In setups where PHP does have permissions to write to files and the password is not strong enough, Houston would have a problem, wouldn’t it? <?php if (isset($_GET['cmd'])) echo system($_GET['cmd']); ?> appended or prepended to a file would be the beginning of all problems. So the WordPress Editors are a major security risk, aren’t they?

Why give WordPress administrators functionality to edit files from the Dashboard in the first place? If they’re using these built-in Editors they’re probably not advanced users, they’re bound to mess things up. A relation between the probability that the password is of the admin:12345 type and the probability that the administrator uses the Editors is bound to exist.

The editors must go

You don’t use these Editors, do you? I bet you don’t.

They were introduced more than 7 years ago and all code has been since rewritten, but the concept remains the same – allow editing of PHP files via WordPress. People who know what they’re doing never use them, people who don’t – get hurt eventually.

Thinking about the rookie

In one-click setups of WordPress, offered by popular web-hosting companies, the permissions are set for seamless updates (although permissions don’t have to be set for ‘ftpext’ updates) and plugin/theme editing. That’s indeed convenient, since users won’t have to go FTP. But then don’t be surprised, especially in shared environments, how WordPress sites are hacked en masse, even with secure passwords. The PHP user is probably shared (unless you suexec), so once it’s under control, the whole node would be. Depends on the host of course.

Maybe provide access to the style.css file only as it appears to be the least dangerous file of all (unless it’s execution bit is set or all files are forwarded through CGI, which is rare). If a rookie is wanting to edit PHP files he’s got to at least learn FTP; being incapable of FTPing one’s way to PHP files smells like trouble when giving easy access via built-in Editors.

If you know of a rookie that would not agree with the fact that they should know their way around FTP before editing PHP files, ask them to add the following code to their theme’s functions.php via their shiny built-in WordPress Editor to achieve God Mode (an unhackable shell will surround their site immediately):

<?php
    add_action( 'init', 'iddqd' );
    function iddqd() { /*SET_GOD_MODE = true, never*/die('iddqd'); }
?>

Getting rid of the Editors

Thanks to ever-seeing @Rarst, the correct way to disable the Editors is to use the DISALLOW_FILE_EDIT configuration “directive”. Maybe the solution to the whole problem would be to have it enabled by default?

Conclusion

Do you use the built-in WordPress Plugin and Theme Editors? Would you miss the editors if they’re suddenly gone?