Spring Sale! Save 30% on all books w/ code: PLANET24
Web Dev + WordPress + Security

Important Security Fix for WordPress

The other day, my server crashed and Perishable Press was unable to connect to the MySQL database. Normally, when WordPress encounters a database error, it delivers a specific error message similar to the following:

[ Screenshot: WP Default Database Error Page ]
Default database-error message

This customizable database error message explains the situation to visitors and circumvents any malicious activity involving exposed scripts, PHP errors, and other issues related to unexpected database issues.

That sounds nice, but there is a problem

The problem that I painfully discovered when my server crashed is that WordPress does not always display the default page for all database-related issues. Apparently, if the database is missing entirely, WordPress assumes that it has not yet been installed and loads the Installation Page:

[ Screenshot: WP Installation Page ]
WordPress Installation Page

Yikes! This is exactly what happened when my server crashed, MySQL was unavailable, and the WordPress Installation Page was displayed to over 100 visitors while I scrambled to resolve the issue.

During the event, there were several attempts to assume control of my site through the Installation Page. Fortunately, I was working on the site (via FTP, cPanel, phpMyAdmin, and so on) during the attacks, and was able to terminate an inevitable hostile takeover.

“john@greatCampingTrips.com”, I’m staring at you here.

It happened to me, and it could happen to you

To me, this scenario represents an enormous security risk for all currently available versions of WordPress (up to 2.8 at the time of this writing). If WordPress serves up the Installation Page the next time your database goes down, anyone could easily gain full control of your entire server. By simply entering an email address and specifying a blog title, an attacker would administratively re-install WordPress and receive the following message:

[ Screenshot: WP Installation Success ]
WordPress installation-success message

Ouch! This is no good. I was fortunate enough to have been there during the incident, however it could have happened while I was away from the computer. What if I had been asleep, at work, or on vacation? Trust me, it doesn’t take long for a savvy attacker to annihilate an entire server, and the damage may be irreversible.

A temporary solution, until WordPress does it better

After restoring full functionality to my site, deleting multiple “Hello world!” posts and “About” pages, and removing the newly added Administrator, it was time to prevent this situation from happening again. The easiest way to do this involves deleting, blocking, or modifying the wp-admin/install.php file, which contains the script that generates the Installation Page.

Until WordPress incorporates a better solution, I recommend one of the following three fixes:

Fix #1: Just nuke it

Simply delete the wp-admin/install.php file entirely. It is not needed after installation.

Fix #2: HTAccess to the rescue

Place the following slice of HTAccess into your site’s web-accessible root directory to prevent access to your install.php file:

# PROTECT install.php
<Files install.php>
	Order Allow,Deny
	Deny from all
	Satisfy all
</Files>

Fix #3: Replace it with something safe and useful

Replace the insecure version of the file with something secure and informative by following these quick steps:

  1. Rename the original install.php to something like, “install_DISABLED.php” or whatever.
  2. Create a new file named “install.php” and add the following code:
<?php // install.php replacement page: https://perishablepress.com/press/2009/05/05/important-security-fix-for-wordpress/ ?>
<?php header("HTTP/1.1 503 Service Temporarily Unavailable"); ?>
<?php header("Status 503 Service Temporarily Unavailable"); ?>
<?php header("Retry-After 3600"); // 60 minutes ?>
<?php mail("your@email.com", "Database Error", "There is a problem with teh database!"); ?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml" lang="en">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<title>Error Establishing Database Connection</title>
	</head>
	<body>
		<img src="images/wordpress-logo.png" />
		<h1>Error Establishing Database Connection</h1>
		<p>We are currently experiencing database issues. Please check back shortly. Thank you.</p>
	</body>
</html>

Once uploaded to your server, this new install.php file will prevent any malicious behavior by serving up a static web page. Now, instead of showing the Installation Page when your database is unavailable, WordPress will display the following message:

[ Screenshot: WP Database Error ]
WordPress installation replacement page

In addition to displaying this information to your visitors, the Installation Replacement Page also performs the following actions:

  • Communicates a 503 (Service Temporarily Unavailable) status code to clients and search engines
  • Instructs clients and search engines to return after 60 minutes (configurable)
  • Sends an email informing you of the situation so that you may take action

To use the Replacement Page, don’t forget to specify an email address in the fourth line. You may also change other variables, such as the time duration, email subject, or email message. If you need any help with these variables, please leave a comment. I have also made the Installation Replacement Page available for easy download:

Download install.php replacement fileVersion 1.0 ( 655 bytes ZIP )

Live long and prosper

Until the developers at WordPress implement a cleaner, more permanent solution for this issue, I highly recommend applying one of the solutions provided in this article. There is no reason to keep the original install.php file after you have installed WordPress, so feel free to delete, modify, or block it. Trust me, dealing with the trauma of watching your site get hijacked by some unscrupulous cracker whore just ain’t worth the pain.

Update

MustLive provides more insight into the install.php vulnerability via this comment and this article: Attack on Abuse of Functionality in WordPress. Many thanks to MustLive for his work on this security issue!

About the Author
Jeff Starr = Fullstack Developer. Book Author. Teacher. Human Being.
The Tao of WordPress: Master the art of WordPress.

86 responses to “Important Security Fix for WordPress”

  1. Jeff Starr 2009/05/05 1:06 pm

    @Mark Jaquith: Apparently MySQL thought that I did, because the install page was definitely served.

    @Steve Taylor: That may have been what happened, but I can’t be sure — the whole event happened very quickly and I am not privy to much of what goes on behind the scenes on my shared server.

  2. Mark Jaquith 2009/05/05 1:11 pm

    if MySQL’s unavailable, how does WP get re-installed? Did your crash involve MySQL going down, then coming back minus your WP database?

    That must be what happened. It’s strange, to say the least. I’ve never seen that happen before.

  3. Jeff Starr 2009/05/05 1:15 pm

    @Mark Jaquith: Me neither, but it certainly scared the crud out of me — you should have seen me racing through the neighborhood running stop signs so I could get home and fix the issue before someone decided to take my site down. Scary stuff.

  4. Easy Computer Fix 2009/05/06 8:37 am

    Doesent wordpress already recommend removing install.php upon installation?

  5. Matthew Muro 2009/05/06 9:14 am

    “Doesent wordpress already recommend removing install.php upon installation?”

    After reading this post, I searched through the Codex and wasn’t able to find anything.

  6. Thank’s Jeff…So glad you posted this.
    I made sure to delete install files on other scripts I use too…there’s really no need for them to be there after you install stuff…it’s like leaving your keys in the door!

  7. Thanks for sharing this. I’m going w/ option 3 as you’ve certainly made it easy enough to do!

  8. Is it a fair assumption that the bad guys are trolling wp sites looking for a down db? In your investigation, have you been able to identify the signature of any such trolling?

  9. I have my wp-admin protected. But thanks for the tip, I renamed the file anyways…

  10. Matthew Muro 2009/05/07 11:55 am

    This would seem to be a rare issue, but it’s better to be safe than sorry.

  11. Terje Asphaug 2009/05/08 8:16 am

    Thanks :) Usually I delete the install.php after WP is installed, but had forgot it this time. It’s now deleted ;)

  12. Blog design Lab 2009/05/08 2:18 pm

    Thanks for this tips !

Comments are closed for this post. Something to add? Let me know.
Welcome
Perishable Press is operated by Jeff Starr, a professional web developer and book author with two decades of experience. Here you will find posts about web development, WordPress, security, and more »
BBQ Pro: The fastest firewall to protect your WordPress.
Thoughts
I live right next door to the absolute loudest car in town. And the owner loves to drive it.
8G Firewall now out of beta testing, ready for use on production sites.
It's all about that ad revenue baby.
Note to self: encrypting 500 GB of data on my iMac takes around 8 hours.
Getting back into things after a bit of a break. Currently 7° F outside. Chillz.
2024 is going to make 2020 look like a vacation. Prepare accordingly.
First snow of the year :)
Newsletter
Get news, updates, deals & tips via email.
Email kept private. Easy unsubscribe anytime.