Three tips to protect your WordPress installation

by on January 17, 2008

in How to,Linux/Ubuntu,Weblog/blog

Here are three easy but important ways to protect yourself if you run a WordPress blog:

  1. Secure your /wp-admin/ directory. What I’ve done is lock down /wp-admin/ so that only certain IP addresses can access that directory. I use an .htaccess file, which you can place directly at /wp-admin/.htaccess . This is what mine looks like:

    AuthUserFile /dev/null
    AuthGroupFile /dev/null
    AuthName “Access Control”
    AuthType Basic
    order deny,allow
    deny from all
    # whitelist home IP address
    allow from 64.233.169.99
    # whitelist work IP address
    allow from 69.147.114.210
    allow from 199.239.136.200
    # IP while in Kentucky; delete when back
    allow from 128.163.2.27

    I’ve changed the IP addresses, but otherwise that’s what I use. This file says that the IP address 64.233.169.99 (and the other IP addresses that I’ve whitelisted) are allowed to access /wp-admin/, but all other IP addresses are denied access. Has this saved me from being hacked before? Yes.

  2. Make an empty wp-content/plugins/index.html file. Otherwise you leak information on which plug-ins you run. If someone wanted to hack your blog, they might be able to do it by discovering that you run an out-of-date plugin on your blog and then they could exploit that.
  3. Subscribe to the WordPress Development blog at http://wordpress.org/development/feed/ . When WordPress patches a security hole or releases a new version, they announce it on that blog. If you see a security patch released, you need to upgrade or apply the patch. You leave yourself open to being hacked if you don’t upgrade.

And here’s a bonus tip: in the header.php file for your theme, you might want to check for a line like

<meta name=”generator” content=”WordPress <?php bloginfo(’version’); ?>” /> <!-– leave this for stats please -->

I’d just go ahead and delete that line or at least the bloginfo(‘version’). If you’re running an older version of WordPress, anyone can view source to see what attacks might work against your blog.

Hat tip to Reuben Yau and Shoe.

Update: In the comments, Joshua Slive pointed out that the .htaccess file shouldn’t have a <LIMIT GET> around the IP addresses. That would have allowed IP addresses to POST, for example. Joshua, thanks for the pointer to the Apache docs on this point.

{ 153 comments… read them below or add one }

Brajeshwar January 17, 2008 at 10:45 pm

1. Why would this IP restriction be more effective than a password protection using the similar .htaccess and .htpasswd method which offers the same level of protection sans the changing of IPs when you move/travel. And let your browser/keychain remember you password so you can just hit enter when prompted.

2. I’m pretty sure most web host have directory browsing turn-off by default and in that case, won’t it show a 404 page thus going to that location makes no sense. However for those not doing that, I’m pretty sure they have a reason and if they’re to follow your steps, they must have been smart enough to do a directory browsing off through their Web Host Panel or through .htaccess.

3. This is the least updated feed and we’re talking about WordPress, you’ll definitely hear about new releases within days unless you’re on an extended vacation.

Reply

Bob January 17, 2008 at 10:56 pm

And don’t let Google know you are doing paid blog postings on your WordPress blog….

Reply

Multi-Worded Adam January 17, 2008 at 11:00 pm

LMAO!

Dude, I love the reverse DNS on those IPs. That’s some classic geek humor right there.

http://whois.domaintools.com/64.233.169.99

http://whois.domaintools.com/69.147.114.210
http://whois.domaintools.com/199.239.136.200

Gotta love the conflict of interest between “home” and “work”. But the NYT moonlighting…you gonna start writing freelance op-ed SEO articles? :D

Reply

Gary Jones :: BlueFur.com January 17, 2008 at 11:06 pm

If your the root user on the server set the ownership of the file to root so only the root user can modify it.

Reply

travis lane January 17, 2008 at 11:12 pm

Just out of curiousity–if the IP address trick prevented the hack–how did you know it would’ve been successful otherwise?

Lots of people do random scans on the wp-admin directory.

Reply

Johannes January 17, 2008 at 11:20 pm

Security through obscurity, great tip :-)

Reply

Vlad - Small Business and Web Design January 17, 2008 at 11:37 pm

I tried to password protect /wp-admin/, but my WordPress took it seriously and instead of asking for login/password combo it dumps me straight to the index page. Never seen this before.

Reply

marty January 17, 2008 at 11:52 pm

Rather than creating a blank index.html in the plugins directory to prevent directory browsing, you can disable it by adding the following to your .htaccess file, and the webserver will return a 403:

# prevent directory browsing
Options -Indexes

Reply

Alvaro January 18, 2008 at 12:14 am

Hi Matt,

you could replace the 2nd point with another configuration of the .htaccess file:

Options FollowSymLinks
AllowOverride None

(You should put the right path to the plugins directory)

or

Options -Indexes

Reply

Boring Market January 18, 2008 at 12:51 am

Great tips!

Reply

Iliyan Darganov January 18, 2008 at 1:28 am

Hi, Matt
thanks for the great tips.

Another way to protect your wp-content folder is again with .htaccess:

Order Allow,Deny
Deny from all

Allow from all

Reply

Dean Clatworthy January 18, 2008 at 1:29 am

Nice bit of irony with your work IP address there Matt :P

Reply

Iliyan Darganov January 18, 2008 at 1:33 am

Ops, the htaccess content did not visualise correct. Here is a screenshot: http://img339.imageshack.us/img339/7439/htaccess1dp4.gif

Also have in mind that the version of WordPress is not shown only in the meta tag. You can find it in the rss feed for example and in several other places.

Reply

Youssef CHAOUI January 18, 2008 at 1:42 am

Great post, for those who run under linx and have cpanel, you can just lock the wp-admin via the interface “Password Protect Directories” it’s more simple.

Reply

leafduo January 18, 2008 at 2:29 am

I think “Deny from all” is better.

(2nd point)

Reply

Jeff January 18, 2008 at 3:13 am

Now that you’ve told the world your IP addresses, won’t hackers be able to spoof theirs to yours to gain access?

Reply

Tim Wintle January 18, 2008 at 3:35 am

lol, thanks Dean Clatworthy, I wouldn’t have even looked at it otherwise :-)

@Matt Cutts – I think that this post will probably help webmasters in general more than any of the specific tips you give to site owners.

I’d have assumed that wordpress would have come with .htaccess files to secure the plugins directory. Perhaps you should suggest it to the wordpress developers?

btw, WEBSPAM-UK2007 is out. Sure you’ll be having lots of fun with it :-) – I was thinking of playing with it myself at home to test the [tiny] hadoop cluster I’ve just set up, but I’ve got another plan for that so it may have to wait … (I don’t have anything like the “infinate” number of processors Google seems to have, so running both jobs is out of the question)

@travis lane – if anyone tries to see my admin pages I class it as trying to hack in – perhaps with no damage, but it’s still something I would like to stop.

Oh, and some of you may be interested in a study I did recently on the growth of online video – see my blog for a link to it.

Reply

joshnunn January 18, 2008 at 3:39 am

What might someone use if they don’t have a reliably stable IP address?

Reply

Tim Wintle January 18, 2008 at 3:57 am

@ joshnunn – I don’t have that much experience with wordpress, but I would try one of the following if you really want lock-down:

- ssh tunnel in through a reliable ip address if you know how to do that

- rename your wordpress admin directory (not sure if this causes any problems with wordpress)

- set the wordpress admin directory to require a secure password and username

but not many of us will have as many people trying to hack our sites as I guess Matt does

Reply

Case Stevens January 18, 2008 at 4:27 am

Hi Matt.
Great tips.
I also took the vulnerable MYSQL settings out of the wp-config file, uploaded them in a separate file which I include in the wp-config.
Would that be an extra safety lock in your opinion?
Regards and thanks for the tips.
Case

Reply

Free WordPress Templates January 18, 2008 at 4:37 am

Instead of limiting the /wp-admin/ directory to only IPs via your .htaccess file, I just password protected the /wp-admin/ at the directory level. Then you can access it from anywhere in the world on a per user-level.

~David

Reply

PhotoTiki Chris January 18, 2008 at 5:08 am

As mentioned above, I think Options -Indexes is a better option for point 2 and can be added to point 1.

This way if you have an open directories in your installation they will be protected.

Reply

Lee January 18, 2008 at 6:25 am

Wow what a coincidence I wrote about these on Jan 9.
http://www.epiblogger.net/5-wordpress-security-essentials/

Amazing how things go around.

If you don’t have a static IP address you can use a range in the htaccess file for your ISP than at least it is narrowed down to just IP’s from your ISP. Check out Login Lockdown as well. It bans people by IP address if they enter the wrong user name and password after so many attempts.

Reply

Brian January 18, 2008 at 6:33 am

joshnunn’s and Tim Wintle’s comments have got me pondering now. Can anyone come up with a script that can ping a FQDN, translate it to an IP, and replace an old IP in an .htaccess file with the new one? This might be an elegant solution to my dynamic IP issue.

Another thought occurs – this would make for a great WordPress plugin! [aligns black candles in a pentagram] Joost De Valk, I invoke you…

Reply

Joshua Slive January 18, 2008 at 6:49 am

Your Apache httpd configuration is not secure. You need to delete the and lines. With these lines in place, you are explicitly ALLOWING access with any other method (POST, PUT, DELETE, etc). And many applications will be happy to serve requests using arbitrary methods (BLAH, for example). If you delete those two lines, all methods will be restricted, which is what you want.

The fact that this incorrect and dangerous configuration has persisted so long on the web (it hasn’t been correct since the NCSA days over 10 years ago) is an interesting phenomenon in itself. You obviously copy-pasted it from somebody else, who copy-pasted it from sombody else, etc. Nobody bothered to check the Apache httpd docs.

Also, less importantly, all the Auth* directives should be deleted since you aren’t using user authentication.

Reply

Joshua Slive January 18, 2008 at 6:51 am

Hmmm… your blog ate the most important part of my comment because it was between angle brackets. Seems kind of lame.

You need to delete the
Limit GET
and
/Limit
lines (with angle brackets).

Reply

Omar Yesid Mariño January 18, 2008 at 6:54 am

Thank you very much, Matt. This is really useful for me. Security on Internet is never enough.

Reply

Brian McDowell January 18, 2008 at 7:00 am

Thank you for this write up Matt. I am sure this quick post will help many people (myself included). I run multiple blogs and am in the process of implementing this.

Much respect.

Reply

Ben Rabicoff January 18, 2008 at 7:18 am

Great tips Matt. I’m more than sure this could save people from a great deal of headaches! :)

Reply

Maurice January 18, 2008 at 7:26 am

I hope the ip adresses are fakes did you realy mean to give out your home ip address :-)

Reply

Brian January 18, 2008 at 7:37 am

Try browsing his “home address” on port 80. :D

Reply

Maurice January 18, 2008 at 7:57 am

:-) Just checking Matt

I have seen some boo boos where people have left things in they should’t have the cc/dd ap that had “passwd” as the password for example they had for got to change the example code that the gate way provider provided.

Reply

Matt Cutts January 18, 2008 at 8:19 am

travis lane, thanks to a kind person, I saw an attack against my blog before it got widely noticed.

Brian, I like the “require username and password” as the simplest option compared to writing that script.

Reply

Matt Cutts January 18, 2008 at 8:20 am

Dean Clatworthy, I picked the IP addresses as a little inside joke for the detail-oriented. :)

Reply

Matt Cutts January 18, 2008 at 8:21 am

Tim Wintle, thanks for the tip. I’ll have to check how we did. :)

Reply

Colin Smillie January 18, 2008 at 8:26 am

I’m suprised Akismet wasn’t mention with regards to spam prevention or even Defensio. I think most WP installations are plagued by comment spam now…

Reply

Garry Conn January 18, 2008 at 8:30 am

Matt,

That’s great stuff man… more awareness about WordPress security is definitely needed. There are so many people out there who are discovering blogging for the first time. They don’t know anything about programming, php, MySQL, etc… they are just merely creative people and writers who want to broadcast their writing on the Internet.

This is an awesome tip, because I think it is something that many installers can automatically include for their clients when they design, install, configure WordPress. I know that I’ll use it. Thanks for the great article.

Best Regards,
Garry Conn

Reply

Michael Clark January 18, 2008 at 9:03 am

Matt, your bonus tip isn’t enough. WordPress publishes your WP version number in lots of public places, such as in your feed. Use the noversion plugin found at http://blogsecurity.net/wordpress/bs-wp-noversion/ to hide your WP version number.

Reply

Tim Linden January 18, 2008 at 9:11 am

Is there a reason it’s only limiting GET and not POST also?

Reply

Nick-R January 18, 2008 at 9:40 am

Cheers for the post Matt,
i use wordpress a lot, its a great way of installing RSS into a site and a simple content management system for people who are non-computer literate .

Please keep us posted with any other faults that may be present.
Cheers
Nick R

Reply

Nick - I think the original Nick here. January 18, 2008 at 9:59 am

Great tips mat. You can also put -Indexes in the .htaccess file to block all open folders on the site.

Reply

Mich January 18, 2008 at 12:14 pm

More gold Matt, I swear from now on I’m reading your feed first thing every day. I would have never thought to use an ht lockout just for admin section. This was an awsome idea and I am going to setup some clients like this if I can think of a way to script an auto update to match dynamic ip changes.

I always just drop an index.htm in if I wanted to keep people out. But that is just to keep out the casual hacker, i ummmm.. errrr… ah hem, am pretty sure most of us know a determined foe will get in if they really want to.

This one great, wow(yes again with the WOW) it will effectively lock out almost anyone even those who really know their stuff will choke on that.

As always my friend Peace and thanks

Mich D.

Reply

Kshitij January 18, 2008 at 12:51 pm

That aint gonna work with dyna IPs. Perhaps if one could rename the directory or move it somewhere else :) .

Reply

Ben January 18, 2008 at 2:26 pm

I would also put out there keeping your installation of WordPress up to date very good for security.

Reply

Dan January 18, 2008 at 2:32 pm

When I created the .htaccess file, I was blocked from my admin directory. I double-checked, and I know that I entered the correct IP address, and I know that my ISP doesn’t change my IP address. When I go to login, the login page appears unstyled (meaning the css for the page has been blocked) and then it sends me to the “Page not found” message on my blog. Any idea what might be causing the problem?

Reply

Robert January 18, 2008 at 3:02 pm

> allow from 64.233.169.99

So WordPress is the REAL technology behind Google? Unbelievable! Waiting for the other Matt to confirm this…

Reply

louis w January 18, 2008 at 3:19 pm

why don’t you just put a password on the admin dir using htaccess. if your password is strong enough its just as good as ip restriction. i doubt a spammer is going to try to crack a pw.

Reply

g1smd January 18, 2008 at 5:21 pm

When you protect a folder from access using the methods above, the URL returns a 403 error.

That still shows that viewer that the folder does actually exist, if they want to go dig a bit deeper.

If you internally rewrite the bare folder-only URL (both with and without a trailing slash) to an internal pathname that really does not exist, then you will serve a 404 error – just like all the other URLs on the site that do not exist.

RewriteRule ^protected/?$ /thisdoesnotexist [NC]

Fun with .htaccess and rewrites.

Reply

Erek Dyskant January 18, 2008 at 5:31 pm

Really neat ideas. Not just for wordpress, but everyone should limit the administrative functions of their web applications to known trusted IP addresses. It’s really amazing how much damage can be done with a little social engineering or packet sniffing for passwords.

Just one comment on your implmentation. the lime still allows POST requests, so I was still able to access your wp-admin page by creating a small html file:

and clicking the submit button.

You shouldn’t even need a directive. If you really want one: it should be:

order deny,allow
deny from all
# whitelist home IP address
allow from 64.233.169.99
# whitelist work IP address
allow from 69.147.114.210
allow from 199.239.136.200
# IP while in Kentucky; delete when back
allow from 128.163.2.27

deny from all

Reply

Erek Dyskant January 18, 2008 at 5:38 pm

My previous comment got garbled by the cross site scripting protection.
Here it is reproduced, except with parentheses instead of greater than and less than signs:

Really neat ideas. Not just for wordpress, but everyone should limit the administrative functions of their web applications to known trusted IP addresses. It’s really amazing how much damage can be done with a little social engineering or packet sniffing for passwords.

Just one comment on your implmentation: The (Limit GET) directive still allows POST requests, so I was still able to access your wp-admin page by creating a small html file and clicking the submit button, so my browser requests the page as a POST instead of a GET:

(form method=POST ACTION=http://www.mattcutts.com/blog/wp-admin/)
(input type=submit)
(/form)

Your system should work fine without the (Limit) and (/Limit) lines, but if you really want them it should look like:

(Limit GET POST PUT)
order deny,allow
deny from all
# whitelist home IP address
allow from 64.233.169.99
# whitelist work IP address
allow from 69.147.114.210
allow from 199.239.136.200
# IP while in Kentucky; delete when back
allow from 128.163.2.27
(/limit)

(LimitExcept GET POST PUT)
deny from all
(/LimitExcept)

Reply

spamhound January 18, 2008 at 5:57 pm

I go one step further and password protect the wp-admin directory in the control panel.

You can also turn indexing off for that plugin folder as added security.

Reply

Dave January 18, 2008 at 6:30 pm

LOL at those IP’s!!!

Reply

Afriend January 18, 2008 at 7:02 pm

To determine which content to display you have trusted ip’s,non trusted,and identified abuse ips then you vary the dispay of content as follows…….

1.Trusted ip (all content)
2.Non trusted ip (frame content or ajax content)
3.Ip abuse Ajax content only

Please delete

Reply

Afriend January 18, 2008 at 8:25 pm

Knowing enemy: Heres the list of 3 advertisers that support of spam sites the most.

1. Googleadsense and Doubleclick.
2. Yahoo
3. Ask

Reply

ganes | gadget January 18, 2008 at 8:32 pm

matt, about point 2. If i know the name of exploitable plugins, I can still access the plugins file. This if you only add index.html file to protect it.

I think it’s better to add

Options All -Indexes

into htaccess file in the root directory.

what say you, matt?

Reply

Ajit Gaddam January 19, 2008 at 8:25 am

Excellent Tips Matt. I added some more WordPress Security Tips to go along with those you listed out here

Reply

Kaloyan K. Tsvetkov January 19, 2008 at 11:08 am

I’d just go ahead and delete that line or at least the bloginfo(’version’). If you’re running an older version of WordPress, anyone can view source to see what attacks might work against your blog.

This is useless. Even if you hide the WordPress version from the header file of your theme, it will still show itself on the login page (wp-login.php). Here is an example with this blog, which I got from here:

…link rel=’stylesheet’ href=’http://www.mattcutts.com/blog/wp-admin/wp-admin.css?version=2.3.2‘ type=’text/css’ …

See, the WP version pops up in the CSS declaration (in bold).

Reply

Kaloyan K. Tsvetkov January 19, 2008 at 11:19 am

Make an empty wp-content/plugins/index.html file. That’s fine and easy, but using .htaccess for the plugins is what I do and it works better then the index.html file before even with the index.html file the “hackers” can probe you to see if you have the plugin that they want to exploit. This is because hardly anyone changes the name of the plugin files or the folders the plugins file are stored in (plus there are a lot of sloppy WP plugins that will not work unless they have the “original” filename and location). Here’s an example: imagine there is an exploit in the akismet plugin, so you need to see if it is installed. There are several things you can do:

* try to load the URL for the folder where “akismet” should be – in the case of this blog it is accessible:

http://www.mattcutts.com/blog/wp-content/plugins/akismet/

You can see that it is accessible, and you can see the date it is uploaded, so you can figure out what could be the latest version of it (knowing the date of the latest release for the plugin in question).

* the above is not the case with all the blogs – some of them got the “index” option of the webserver disabled so they got 403 Forbidden error when they try to load the index for the “akismet” folder. In that scenario just try to load the plugin file itself – like this:

http://www.mattcutts.com/blog/wp-content/plugins/akismet/akismet.php

If the file is there you will see something like:

Fatal error: Call to undefined function add_action() in /usr/www/users/cutts/blog/wp-content/plugins/akismet/akismet.php on line 25

Those two “probing” scenarios are the reason I prefer to use .htaccess for my plugins folder, cutting off all web access to it.

Reply

Kaloyan K. Tsvetkov January 19, 2008 at 11:22 am

Make an empty wp-content/plugins/index.html file.

Another thing about this matter – you should fo this index.html thing to the /themes/ folder as well. Nowadays the themes are full of extra functionality, and soon there will be exploits for them as well, and an extra index.html prevention there will be OK.

Reply

Bruce Keener January 19, 2008 at 11:33 am

Excellent tips!
Took me a while to remember though that the quote marks do not copy properly when copying code directly from your post … it is necessary to edit to ensure real quote marks are used.

I’ve noted it before, but I am delighted you are in one of your “tech moods.” I enjoy all of your posts, but especially enjoy you breaking out of the mold from time to time.

Reply

Amit January 19, 2008 at 11:40 am

Hi Matt, some nice tips there.

Just want to let you know that on your blog why do u display the meta details that is links to the wordpress admin ? that is also a security hole.

Also locking the wp-admin file with a password protected .htaacess file will be best option. Please correct me If i am wrong.

Reply

shawn January 19, 2008 at 11:52 am

You know Matt, I never thought of or even knew that information. Please put me on your e-mail subscription list and keep me updated. I’d really appreciate that, because:

http://www.Drewryonline.net

are all WordPress blogs….:-)

Thanks again,

Shawn

Reply

Kenji January 19, 2008 at 12:41 pm

Does anyone else loose the dashboard contents after uploading their .htaccess in wp-admin ?

Reply

Dave (The Other One) January 19, 2008 at 2:02 pm

Overkill alert !!!

FYI…

#1 – There’s a little thing called “Apache Web Server” and it comes default with directory indexing turned off. 90% of all hosting companies have it turned off even on Windoze servers.

#2 – If you’re using Permalink’s with WordPress, the .htaccess in your root directory should already cover this.

ahem *cough* *cough*, excuse me Mr. Cutts, but do I see you passing Pagerank to the two links at the end of your article. Did you forget your nofollow tag??? I know things have to be hurting over at the GooglePlex with GOOG stock down by almost 20% but really Matt, I never thought you’d be caught selling text links or writing sponsored blog posts :-)

Reply

Bruce Keener January 19, 2008 at 3:38 pm

Has anyone had trouble getting the Google Sitemaps Generator plugin to update a sitemap after restricting /wp-admin to your own IP address? I did the htaccess mod (thanks again, Matt) and just tried running the sitemap plugin a few minutes ago. It runs but does not seem to be updating the sitemap.

I could work around it by temporarily deleting my htaccess file in the wp-admin directory, but I wonder instead if it is just time to part with using a sitemap. Thoughts? I know it is a bit off topic, but the security updates resulted in me rethinking it. All of my pages have been indexed for sometime, so I do not know that the sitemap really adds any value.

Reply

Joshua Slive January 19, 2008 at 4:08 pm

I’m very surprised you haven’t corrected this entry yet, and disturbed by the number of people who are copy-pasting your broken example. This configuration has one of the most dangerous kinds of security problems: one which does not show up in a basic test, but is easily exploitable by someone who knows what is going on. Your site may or may not be exploitable at the moment; it depends on the details of your wordpress configuration. But in any case, why would you recommend an incorrect and possibly exploitable configuration when the correct and secure configuration is simpler than the incorrect one.

If you don’t believe me that your use of Limit is wrong, just read the bold print in the apache httpd docs:
http://httpd.apache.org/docs/2.2/mod/core.html#limit

Reply

SEO Tracker January 19, 2008 at 4:52 pm

WOW! I would not have thought of this! Thanks Matt!

Reply

Tony January 19, 2008 at 5:44 pm

Matt how do you modify the htaccess if you a dynamic ip address?

Reply

IncrediBILL January 20, 2008 at 2:29 am

I had WordPress on one of my servers and I found the easiest way to protect nyself was to get rid of WordPress.

Reply

Robert Accettura January 20, 2008 at 10:14 am

Because I’m a nice guy, I’ll throw you a few more good mods:

Use Admin SSL to force SSL for your blog’s login, otherwise your password is plain text and anyone can sniff it out.

Add to your .htaccess file:

IndexIgnore *

To never show indexes. That way someone can’t browse subdirectories in wp-content/plugins.

Reply

Kenji January 20, 2008 at 1:09 pm

A follow-up on my problem with the dashboard.

It does show-up if I access it through the …wp-admin/ but does not if I click on the dashboard button (url ends in wp-admin/admin.php?page=index.php).
This might not be a side-effect of the .htaccess after all.

I have also checked the Sitemap plugin and it failed to write the sitemap file.

Reply

David Saunders January 20, 2008 at 2:07 pm

I’d be happy if I could find a nice WP host that could set up a template I have ready and exclude the date part plus add the title, description tag in and add Google Analytics, Verification……

Plus all the nifty plug ins with no hassle….. Feel free to mail me if you know a really good, reasonable host that can get it right – please don’t say the Y! word…….

HELP!!!!

Reply

Tom Forrest January 20, 2008 at 4:33 pm

I own several WordPress based sites.

Does anyone know of a good consultant I could hire to do this for me? Matt, thank you for this very useful post, and excellent examples of exactly what needs to be done.

Tom

Reply

Matt Cutts January 20, 2008 at 10:53 pm

Joshua Slive, I’ve updated the post — thanks for pointing that out.

Reply

Multi-Worded Adam January 21, 2008 at 8:01 am

Hmmm… your blog ate the most important part of my comment because it was between angle brackets. Seems kind of lame.

You need to delete the
Limit GET
and
/Limit
lines (with angle brackets).

This is a WordPress thing, Joshua. It’s done (at least such is my understanding) to prevent people from arbitrarily putting in things like iframes and Javascripts that lead to other sites. The way around it is to explicitly type the &lt; and &gt; , rather than the < and > signs.

So…in the case of your example, you’d type &lt;LIMIT GET&gt; . It’s messed up, but it does work.

Reply

William January 21, 2008 at 8:52 am

I did not see this mentioned, I apologize if I am repeating a previous post, but thought you might find it interesting…

One other thing you may wish to consider is a little header trickery. Simply using allow/deny does not effectively hide the files and folders in question. The user will see a 403 Forbidden message. A determined attacker could still gain access to the protected files once that attacker has determined the files exist. Yes, it would be difficult and unlikely, but not entirely impossible. You can more effectively hide these files by adding the following lines outside of the folder section of your .htaccess file:

ErrorDocument 403 whatever/youuse/for404.errors

Then, in your error handling document (guessing you use PHP) add the following line at the top:

header(‘HTTP/1.1 404 Not Found’);

To a would-be attacker searching for hidden files, they would not be able to distinguish a blocked area of your site from a folder that does not actually exist. Another benefit is that the content would appear to be non-existent to search engines and other automated processes such as malbots.

Reply

Xianhong January 21, 2008 at 7:39 pm

WordPress should release a security patch for their blog. I used to installed 1 wordpress, i never know that. i will make some changes to the blog.

Reply

LoLo January 21, 2008 at 11:19 pm

That bonus tip won’t prevent your version from being leaked. All a person has to do is view the source of any of your feeds to get the same info. Even with FeedBurner cranked up, I can see your category feeds ;-)

Just edit your wp-includes/version.php to change it across the board.

I’d also suggest hiding your entire WordPress install. I just posted info on how to do that along with some other thoughts about your post and put $20 up for grabs for the first person who finds my wp-admin directory.

Reply

Allan Stewart January 22, 2008 at 4:01 am

Matt,

This is very useful, thanks very much. Can I add another tip. If you have a dynamic IP you might consider setting up a proxy script from your webserver and then only allow connections to your WP via the IP associated with the proxy script. You should also .htaccess passwd protect the proxy site.

I find this very useful.

Ta

Allan

Reply

Peter Westwood January 22, 2008 at 6:07 am

And here’s a bonus tip: in the header.php file for your theme, you might want to check for a line like

<meta name=”generator” content=”WordPress ” />

I’d just go ahead and delete that line or at least the bloginfo(’version’). If you’re running an older version of WordPress, anyone can view source to see what attacks might work against your blog.

You’ll be able to do that with a simple plugin or code in your themes functions.php in the next major version of WordPress – more info on the changes to the WordPress generator generation can be found over on my blog.

Reply

Peter January 22, 2008 at 8:17 am
Don Melton January 22, 2008 at 9:21 am

Matt,

Kaloyan K. Tsvetkov is correct that just removing the WordPress version from the header file in your theme does not prevent it from being visible in the style sheet inclusion from the source of the login page.

However, there are other places where the WordPress version is visible. All of your feeds and OMPL file contain the version. And these are not easily removed without modifying the WordPress source files themselves. Also, the “readme.html” file at the root of your WordPress installation contains the major and minor version number, although the specific revision is not there.

Reply

Terinea Weblog January 22, 2008 at 4:01 pm

Hey by protecting the wp-admin, does this not stop programs like Windows Live Writer from working?

Jamie

Reply

Peter January 22, 2008 at 7:26 pm

Nice article, I just finished my little take on the .htaccess file setup for general security. Besides the Options All -indexes, I also added a few lines to stop browsing the wp-content and wp-include directories.

You can check it out on:
http://blog.avirtualhome.com/2008/01/17/securing-wordpress-part-2/
but make sure you also read the addendum
http://blog.avirtualhome.com/2008/01/22/securing-wordpress-part-2-addendum/

Reply

Amit Bhawani January 22, 2008 at 8:22 pm

Excellent tips there matt, especially hiding the plugins page which currently has helped me access my competitors sites and analyze their plugins :D
I have written a complete wordress security guide @ http://www.amitbhawani.com/blog/wordpress-security-guide-securing-your-wordpress-blogs-from-hackers/

Regards
Amit

Reply

Matt Cutts January 23, 2008 at 12:15 am

Peter Westwood, that’s great news — thanks! On removing the version number, I know that it stays in places like your feeds, but unless you’re facing a determined attacker (which can happen), often just lowering your profile a little bit makes someone lose interest and move on to an easier target.

Reply

Colin Joss January 24, 2008 at 2:04 pm

As I am quite a newbie at wordpress, I really am glad found this article. I don’t think I understand much of it, but doesn’t seem difficult to apply at all.

Colin Joss
East Lothian, Haddington
United Kingdom

Reply

Andrei January 25, 2008 at 4:11 am
Ash January 25, 2008 at 12:02 pm

Hi Matt

Thank you for the great tip. My WordPress site was hacked recently and I am going to implement your tips.

Ash

Reply

Sherif Elsisi January 25, 2008 at 7:44 pm

Great tips, thanks. I have been trying for a while to find out about security issues with wordpress after being hacked and never came across your tip about hiding you plugins directory. This is a good one!
Most hacks I experienced with my customers sites were due to having the default table prefix installed. I strongly recommend that you add changing the table prefix on your wordpress tables to a difficult one. WordPress is popular and everyone knows the table names.
To learn more check out http://blogsecurity.net. They did a great job at addressing topics on wordpress security.

Reply

Colin Joss January 25, 2008 at 8:29 pm

I just come back again to copy this and apply this on my wordpress..

I can “hide” the plugins, but can’t really put the .htacess right.. How to know or determine the deny IP address? Any criteria?

Thank you

Reply

Webguard January 27, 2008 at 9:56 am

I made it easy and protected my /wp-admin dic just with a unusually name and password… i think thats nearly enough in that case

Reply

jonathon January 28, 2008 at 1:35 am

i been using this very same protecting for about a year now and have to say it works very well, apart from sometimes block working files.

Files ~ “.(css|jpe?g|png|gif|js|flv|swf)$”

Reply

ZAFER January 28, 2008 at 9:34 am

How dow WP work with zen cart?

Reply

Singapore SEO January 28, 2008 at 10:43 am

Ah, nice set of tips. Just about to implement it. Anyway, seeing that you love WordPress alot (I should think you do), any chance Google might just be buying them? :p

Anyway, cant you just deny access to the wp-admin folder except to yourself? I mean, I thought its possible to do that =.= Meh. Sorry for the ignorance :|

Reply

Mark January 29, 2008 at 7:43 am

I am having trouble uploading my index.html file into my plugin folder using cPanel.

I am curious about something, Matt, why index.html? Why not index.php?

Reply

Peter January 31, 2008 at 4:47 am

WordPress Security Whitepaper ( downloadable .pdf )

http://blogsecurity.net/wordpress/wordpress-security-whitepaper/

Reply

David Dalka January 31, 2008 at 9:42 am

Great stuff. Thanks.

Reply

Anuj Seth February 9, 2008 at 9:18 pm

Why not just password protect the directory using .htaccess?

That’s what I’ve done. Wouldn’t that be an easier option to deal with?

Reply

Bala Krishna February 19, 2008 at 1:26 am

IP method is good for static IP users.. but not useful with dynamic ip.. however it is great that everybody come up with new ideas to protect blog.. great thanks

Reply

Brian March 11, 2008 at 3:20 pm

Thanks for the tip about putting an index.html file into the plugin directory.

Reply

Raul March 14, 2008 at 12:28 am

I have included the .htaccess file and it works, it only permits my IP address to access the admin interface, however, my site gets hacked on a daily basis by some robot that I guess searchs for wordpress installations.

I’m using the latest version of wordpress (2.3.3)

Any suggestions?

Many thanks

Reply

greggles April 3, 2008 at 6:12 am

What kind of protection does the IP address limitting fix provide? It won’t help CSRF nor XSS based attacks. So…I guess that leaves code execution? Privilege escalation? Can you describe more what you hope to prevent with that?

Reply

Paolo May 6, 2008 at 12:39 pm

Thanks for these tips. they are useful!

Reply

Firewall Script May 8, 2008 at 6:16 am

Don’t know if you checked out DaveN’s recent post about Firewall script, but i’d really recommend it :)

Reply

Halim June 2, 2008 at 10:40 am

If use ip address to block, I suppose it’s not for me because my dynamic ip always changes.

Reply

John Colascione June 6, 2008 at 8:59 pm

Thanks for these suggestions Matt. I’ve implemented some of them… It’s a real shame what’s happening with blog, comment, mail system and forum spam lately… It’s really ruining the net and getting out of control…. Like one bad apple spoiling the bunch, just that there’s a whole lot of bad apples falling….

Reply

IMGem July 31, 2008 at 11:58 pm

Thanks for tips.

I’ve been looking for ways to secure my wordpress sites. Password protected the wp-admin directory seems more easier than ip restriction.

and i always have a blank index file for wp-content, plugins, themes. it’s just a simple step to make thing safe than regret.

Reply

Gary777 August 1, 2008 at 12:40 pm

Matt,

Thanks for the info! I have recently been hit by the Google Malware warning and the cause was a Javascript iFrame hack in my site, I found this post while trying to add security to WordPress.

I wanted to note to your users that changing the value in wp-includes/version.php to hide your version number can create another issue; if you set this to a version number lower than the current version you will always see the “Version 2.x is now available, please upgrade” in your dashboard.

If you set the version number higher (I.E. 4.9 ) then you won’t see a notice for a new version of WordPress in your Dashboard, you will have to proactively check for new updates or you will have to sign up for email notices.

Gary777

Reply

Mahmoud Abozeid August 17, 2008 at 10:41 am

Awesome tips!
I just did it and everything look great.

Cheers,

- Mahmoud

Reply

Toastboy September 25, 2008 at 2:50 pm

I am going to block my wp-admin dir right now. I never even thought of securing that directory to any ip but mine. But it makes sense. I never check my admin from outside my home anyway.

My header showing the version is not going to happen any more either.

Great Site BTW. I am going to read a lot more of your posts.

:-D

Reply

John Hoff - eVentureBiz October 26, 2008 at 6:48 pm

Hello Matt. Those are good tips thanks. If it’s ok with you, I have written a 7 post series on securing your WordPress blog and would like to leave the link (feel free to remove my comment if you don’t approve).

It’s a picture-guided step-by-step tutorial for beginners to learn how to secure their blog. The first post is here:
Fluffy’s Guide To Securing Your WordPress Blog – Post 1.

Reply

autoambulance November 22, 2008 at 12:25 pm

@ John Hoff

Thanks for the post, but where can we find the rest of your posts?

Reply

Michael November 30, 2008 at 6:12 am

I have 5 wordpress blogs. Three of them remember my admin username and password when I log into my admin page. The other two I have to insert my username and password evertime even if I check the box that ask “remember my password?”. Why don’t they remember my username and password like my other three blogs??

Please help. No one seems to know the answer.

Stumped!

Thanks!

Michael

Reply

Kevin Cosmi January 20, 2009 at 7:35 pm

Thank you Matt, this is big help for me while i am working and explore using WordPress Blogs….I realized that this is more useful….

Reply

David Kierznowski February 6, 2009 at 2:26 pm

Its great to hear a few guys mentioning our tools over at http://blogsecurity.net.

Check out our free online WordPress vulnerability scanner if you get a chance… a new version has just been released, although, it still needs a lot of work.

Cheers

Reply

Connie March 21, 2009 at 3:14 am

Two Questions:
If you exclude IP addresses, how can you write to your blog when you are on the road?

What about the way that IP addresses change, as with some ISPs?

Thanks.

Reply

Abhimanyu May 2, 2009 at 10:49 am

Hi, the problem #2 is fixed now in wordpress as it do not show plugins listing. If you are on a dynamic IP, its good not to do #1 step. Although you can use Country IP range.

Abhimanyu
http://mwolk.com

Reply

Richard Vanderhurst May 19, 2009 at 3:48 am

A big thanks to this post… I just applied this on my wordpress blogs. Thanks again!

Reply

ByREV June 13, 2009 at 4:20 pm

i use mysql random passwd, only localhost in mysal connect, strong admin passwd with 14+ chars/numbers, 777 perm only for cache and uploads folder

btw, for mysql injection search in your site with google this words: wellbutrin, adipex, adderall, xanax, carisoprodol … ex: site:http ://your.site.com xanax

more words here: http://www.mattcutts.com/blog/helping-hacked-sites/ after line “The following is some example hidden text we found at”

Reply

Rory Siems July 23, 2009 at 7:45 pm

Hi Matt,

we just spent the day fixing my friend’s wordpress site that apparently had some passthru exploit from a site on a Chinese domain routed through a Russian IP.

We upgraded WordPress to the latest version, we upgraded all of the plugins to the latest version. The web developer who set up the website claimed that the malicious code installed on the site was not from a WordPress vulnerability, but rather from a brute force attack on the web host.

I still am not 100% sure that a dictionary attack or brute force attack guessed the password as it was pretty obscure. To be safe I did subscribe to the wordpress development feed. I like the idea of obscuring plugins from snoops too.

Reply

Redbrickstock August 20, 2009 at 5:37 pm

Will the .htaccess thing work for a class B address. eg. allow from 64.233.169. ?

Reply

doruman August 29, 2009 at 10:26 am

Even if this post has more than a year old, here are very useful informations for any WP blogger. Thank you very much Matt for all that you offer as free informations, not only as Google employer.

Kind regards,
Doru

Reply

Russell September 1, 2009 at 6:43 am

Hi Matt
Hope you doing great!
Our blog has been hacked. Im getting all these wierd backlinks to my blog on other blogs but they hidden. My blog developer says “What the script does, apparently, is create those URL’s on their site (that are linking back to you).”

Thought it would interest you. We are working with Godaddy to fix the problem..

Best

Reply

Kat Young October 4, 2009 at 7:55 pm

I have had my blog hacked over and over. I will try to edit my .htaccess file thanks =)

Reply

Robert Bury November 23, 2009 at 9:41 pm

Thanks for the great resource!!!
To possibly help others…

Step 1) I could only use:
order deny,allow
deny from all
# whitelist home IP address
allow from 64.233.169.99
(anything else crashed and I couldn’t access anything)

Step 2)
I already had a file (maybe an update) and it said:

Bonus Step)
I really had to search for it and ultimately found it in the wp-includes\general-template.php
file.

Thanks so much Matt!!!
~ Robert Bury

Reply

RAY December 2, 2009 at 1:27 am

Q about feedburner feeds that do not validate?

hmmm. wondering why feedburner shows the wp version in its coding if it’s such a security risk and now considered a no-no?

from the feedburner feed code –> http://wordpress.org/?v=abc

but also mainly wondering why feedburner feeds don’t validate (using http://feedvalidator.org/check.cgi?url=hxxp://domain-name.com ) …. it shows lots of yellow highlighted errors such as:

language must be an ISO-639 language code: …
Ensure description precedes content:encoded
Unregistered link relationship: hub
Non-html tag: hs …. <img src="http://feeds.feedburner.com/~r ….
Column 0: Invalid HTML: malformed start tag,
column 0: style attribute contains potentially dangerous content: word-wrap …..

As a newbie i would have thought feedburner had all the formatting protocols taken care of for validation since it refers one to validate a feed there at that site if FB cannot find the feed?

I’m confused about this. Really appreciate any clarification and feedback or solutions on how to fix / validate feedburner feeds properly since I am working on setting up a WP-based site w/ a friend and it’s really like a new language — on alot of this but trying to learn for sure.
thank.s

Reply

iglow January 19, 2010 at 6:22 am

yeah this days a lot of blogs gets hacked, using chmod properly can help much also

Reply

Jon February 13, 2010 at 7:24 pm

There’s a couple of pretty handy plugins that help protect WP:
Secure WordPress – http://wordpress.org/extend/plugins/secure-wordpress/
Wordpress firewall – http://www.seoegghead.com/software/wordpress-firewall.seo

I use them both. The firewall throws out some “false positives” sometimes (I had problems with Google Ad Manager, but you can whitelist stuff).

Reply

Jon March 1, 2010 at 5:55 pm

Hi, me again. I use WordPress a lot, but am not a techy at all. I am very paranoid about things going wrong. I see that you keep the “meta” widget on your sidebar. Now, I try to remove every sign that my site is running on WordPress for fear of those pesky hackers doing naughty things, like killing my site and business! I am guess that as wordpress blogs go, yours must be one of the most popular in terms of traffic, and also get a lot of unwanted attention. Do you ever have any problems with people trying to hack it? Is it much more secure than it used to be? Do you have any other little security tips that you have not had time to publish yet?

Reply

Bruce March 11, 2010 at 9:21 am

Great advise although the htaccess bit was tricky, the issue with quotes being cut and pasted had me going. Adding the password to the directory and adding the security plugins are super ideas. In searching I could not find the string in the header, perhaps it was removed in later versions of wp?

Reply

Ayrılık Büyüsü March 16, 2010 at 7:17 am

yeah this days a lot of blogs gets hacked, using chmod properly can help much also

Reply

Praveen April 12, 2010 at 6:53 am

Wow!!! Nice Stuff buddy…..
Recently there is a attack over WordPress Blogs by Hackers.The saddest part is exploited security Hole not yet Identified,

Dirty Attack Over Hundreds Of WordPress Blogs
http://www.techpraveen.com/2010/04/dirty-attack-over-hundreds-of-wordpress.html

Reply

d3mha April 16, 2010 at 5:55 am

nice tips,
but its useless if you have ADSL , coz ur ip will change everytime
i’ve wrote more tips check it out
http://d3mha.com/null/how-to-protect-your-wordpress/

Reply

Mike May 10, 2010 at 8:46 pm

Is it possible to use a wildcard in the htaccess to designate a range of IP addresses?

Allow from 69.147.114.*** or something like that?

Reply

Mark Maranga June 23, 2010 at 5:44 am

Matt, this is a great advice. Tip #2 and #3 are easy. My problem is, here in my country, I’m using a Dynamic IP address. I really don’t know if there’s any solution to this but I think wildcards such as *** or ??? will do, am I right?

Reply

Harald Kraemer August 8, 2010 at 9:39 am

Hi,

nice tips! I’ve created a small script which helps people without a fixed IP to get all network ranges of their provider. The output can be directly added to the .htaccess file. Here in Germany the script works well for bigger providers, I don’t know how it works in other countries. But I assume it works also in other countries.

The output of the perl script looks like:

allow from XXX.X.XXX.0/24
allow from XXX.X.XXX.0/24
….

The script and some more explanation is available from:

http://technitip.net/2010/08/how-do-you-protect-your-blog-from-hackers/

It’s only needed to replace the netname within the script. On the page it described how to find out the dial-in netname from your provider.

I hope it’s useful.

Greetings from Germany,
Harry

Reply

Alan August 31, 2010 at 1:19 pm

Hi Matt,

Thanks for the tips! To all those suggesting using a password to block access to wp-admin, via cPanel or otherwise, from what I understand, although this method would block access, it would also cause problems with various WP Ajax & possibly other WP functions.

Can anyone confirm this? Thanks!

Reply

Eric September 18, 2010 at 7:27 pm
David October 3, 2010 at 1:01 am

Hi, me again. I use WordPress a lot, but am not a techy at all. I am very paranoid about things going wrong. I see that you keep the “meta” widget on your sidebar. Now, I try to remove every sign that my site is running on WordPress for fear of those pesky hackers doing naughty things, like killing my site and business! I am guess that as wordpress blogs go, yours must be one of the most popular in terms of traffic, and also get a lot of unwanted attention. Do you ever have any problems with people trying to hack it? Is it much more secure than it used to be? Do you have any other little security tips that you have not had time to publish yet?

Reply

Matt January 30, 2011 at 11:17 pm

Matt, thanks for these tips, I find that the folks at wordpress do a great job at securing wordpress as much as possible one thing readers will want to avoid doing is using fantastico or other such services to install wordpress. Reason being it chooses a default name of wp1 or wp2 for your mysql data base username and password, these should be different and it automatically sets your database prefix to wp_ (which is what the native default install does as well, it should be changes to something like $%TGHffke^443#@4

That being said, there are a ton of other things to do but it would be more of a post than a comment.

However, readers may find this plugin helpful as well:

http://wordpress.org/extend/plugins/bulletproof-security/

Hope this helps someone out.

Happy Blogging.

Reply

James March 7, 2011 at 11:39 am

I read most of your posts but I must say that this is the most directly applicable post that I have read yet. If only I had decided to search for WP security posts before I had been hacked instead of after…

Reply

Christian Geek April 12, 2011 at 9:15 am

Hello!

Just a short question. If i restrict admin folder to my IP,
can I enter it with a different IP within my Ftp client?

It wouldn’t be so nice if in any case I lock myself out forever from my WP …

Reply

Grahame k April 14, 2011 at 8:39 am

I love wordpress but the security flaws scare me witless im sure alot of people feel the same, it’s been a while but cheers for the blog matt and i just hope this helps.

Reply

Farid May 7, 2011 at 8:40 am

Definitely some interesting points here. There is definitely a security issue with the blogs in which I myself have had experience.

Reply

Dheeraj June 4, 2011 at 9:47 am

I think the very first point(Tip) is only for those people that are using static IP address. and Third one is really helpful. Because WordPress developer’s main concern is to make It hack proof.

Reply

Sahil Kotak July 16, 2011 at 9:45 pm

I would like to do the same to secure my blog. I will try the 1st Method right now (hope it works!) besides that I also use a plugin (didn’t remember the name) it helps me from the brute force attacks in my Wp Admin login.

Thank you for the tips Matt!

Reply

Bekki July 23, 2011 at 5:30 am

Excellent post Matt.

Its essential to keep your blog secure from being hacked and these tips are spot on!

It took a little time to master the htaccess side of things but all is safe now….thanks for yet another great post to help everyone of us trying to get our sites at their best!

Reply

Matt Fraser July 27, 2011 at 12:00 am

Matt,

Some great tips here.

However, in regards to restricting your ip address, what if you have a dynamic ip verses a static ip, would you still implement this?

Reply

Jrenrock August 16, 2011 at 11:21 am

Protect your folder just add .htaccess file for every folder
the .htaccess must have

# disable directory browsing
Options -Indexes

Edit with notepad and save without extention like “.htaccess”

Reply

Otreva October 9, 2011 at 7:15 am

These are some good tips. There are plenty of users who leave their sites as default who are usually the ones who get hacked.

I have a list of some tips that I use for WordPress Security here:
“http://www.otreva.com/blog/10-steps-to-securing-wordpress/

Reply

Mike October 20, 2011 at 10:13 pm

Seeing how original post was made back in 2008. Had any of thos things been addressed by newer WP versions? Or should we still use the advise given by Matt?

Reply

chris April 17, 2012 at 8:28 am

Good tips – I recently moved from a zeus server set-up to apache as you could not use .htaccess files at all. Trust me a nightmare!

Reply

Leave a Comment

If you have a question about your site specifically or a general question about search, your best bet is to post in our Webmaster Help Forum linked from http://google.com/webmasters

If you comment, please use your personal name, not your business name. Business names can sound salesy or spammy, and I would like to try people leaving their actual name instead.

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Previous post:

Next post: