> You need to start working your way through these resources:
That's a lot of material...!
> Anything less will probably result in the hacker walking straight back into your site again.
I feel as if I've already figured out most of these on my own, but I'm now agonizing over whether I'm simply going to ban WordPress from the server instead. :-(
I have over 100 sites on this server - five of them are WordPress and they already occupy about 90% of my time allocated to supporting the server. So far I've had a couple of sites that repeatedly chewed up my CPU and memory when they got a lot of hits (as I recall, it was some style that was eventually implicated) and two whose MySQL databases became corrupt.
The people on my server are basically using it for blogging. There are numerous other platforms for blogging. And it's unfair to the other ~95 people on the server that they're constantly having trouble because of the 5% running WordPress.
Now, I'm not laying this all at WordPress's door. Being the effective market leader means that people will concentrate their attacks on your platform.
But, by allowing third-parties to put untrusted code into the system as part of styles, you're just asking for trouble. And it isn't even necessarily malicious code - something as simple as a while loop that accidentally goes forever in some cases can bring a server to its knees.
(And PHP is not a great language for security either. But I digress...)
How to harden WP out of the box
Thing is - I don't see why you need to be able run Turing-complete programs in order to make "styles". Indeed, if I wanted to create a platform to encourage exploits, I'd create one which allowed you to hide executable code into a part that people think of as "cosmetic". Loading actual code into your WP installation should be rare, and a big deal - you should be able to do an awful lot of what you want to do in data!
I think that horse has left the barn years ago ;-) but assuming you wanted to maintain backward compatibility (almost always a good idea!), there's one thing you could do that would be very little work and prevent a lot of grief.
The number one issue is very simple - you can drop untrusted code anywhere in the WP installation and then an attacker can run it directly without going through WP code. This is how my attacker got in, and it's the obvious way to go if you're lazy.
But that's easily fixed without affecting your program at all, isn't it? If I read it correctly, you simply never want to run php code in subdirectories independently?
And there are two separate, good ways to fix this - and there's no reason not to do both of them (though they aren't both possible in all installations).
I'm looking here for very easy, low-work, solid fixes - not fancies or huge tasks. (And these might be well-known in your literature, I have more homework to do...)
Part of the issue is that the attack file, lib.php, was directly visible to the web. But what if (most of) the WordPress installation were "strongly encouraged" not to be in the public_html directory - so this code could not directly be executed from the web?
This is what we historically did for, e.g. Perl code back in the day - only the tiny, top level script was even visible to the web server - the rest of it was in a parallel tree but can be called by those top level scripts.
Yes, I know that in some cases the user only has public_html.
And I haven't checked your documentation, but I'll bet that way what you recommend for an installation - that's I think how I have it installed on my server (using apt-get), but the user just dropped his own version into his own server space without realizing we had it.
Here's what I think is a very "light solution" to that:
At startup time, you refuse to run if the WordPress installation is "entirely" in the public_html tree - UNLESS the user sets a configuration flag.
So this is pretty painless for everyone. The first time the naïve user drags the installation onto his public_html and tries to run it, he gets a very clear and polite error message... "Hello, we see that you've put your installation in the HTML tree. You can fix it [....] or if that isn't possible or you just want to try it out, just set this configuration flag [...]"
Now, some part of your installation will still have to be reachable by the webserver directly - or some people can only use public_html.
For this, you can aggressively use .htaccess. By default, .php files should not be executable or even reachable. A specific set of .php files should then be explicitly whitelisted in .htaccess.
There should be almost never any reason to directly be able to execute .php files in a subdirectory, as in my exploit relied on - but even allowing the code to be called from your main program should require a whitelist - and you can put that one into your configuration file and not the .htaccess, which makes it much more convenient for users.
Sorry for the long message - thanks for reading!