Three tips to protect your WordPress installation

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 Responses to Three tips to protect your WordPress installation (Leave a comment)

  1. 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.

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

  3. 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? 😀

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

  5. 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.

  6. Security through obscurity, great tip 🙂

  7. 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.

  8. 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

  9. 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

  10. Great tips!

  11. 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

  12. Nice bit of irony with your work IP address there Matt 😛

  13. 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.

  14. 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.

  15. I think “Deny from all” is better.

    (2nd point)

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

  17. 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.

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

  19. @ 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

  20. 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

  21. 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

  22. 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.

  23. 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.

  24. 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…

  25. 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.

  26. 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).

  27. Omar Yesid Mariño

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

  28. 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.

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

  30. I hope the ip adresses are fakes did you realy mean to give out your home ip address 🙂

  31. Try browsing his “home address” on port 80. 😀

  32. 🙂 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.

  33. 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.

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

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

  36. 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…

  37. 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

  38. 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.

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

  40. 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

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

  42. 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.

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

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

  45. 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?

  46. > allow from 64.233.169.99

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

  47. 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.

  48. 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.

  49. 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

  50. 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)

  51. 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.

  52. LOL at those IP’s!!!

  53. 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

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

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

  55. 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?

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

  57. 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).

  58. 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.

  59. 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.

  60. 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.

  61. 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.

  62. 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

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

  64. 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 🙂

  65. 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.

  66. 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

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

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

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

  70. 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.

  71. 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.

  72. 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!!!!

  73. 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

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

  75. 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.

  76. 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.

  77. 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.

  78. 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.

  79. 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

  80. 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.

  81. 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.

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

    Jamie

  83. 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/

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

    Regards
    Amit

  85. 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.

  86. 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

  87. Hi Matt

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

    Ash

  88. 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.

  89. 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

  90. 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

  91. 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)$”

  92. How dow WP work with zen cart?

  93. 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 😐

  94. 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?

  95. WordPress Security Whitepaper ( downloadable .pdf )

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

  96. Great stuff. Thanks.

  97. 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?

  98. 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

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

  100. 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

  101. 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?

  102. Thanks for these tips. they are useful!

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

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

  105. 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….

  106. 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.

  107. 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

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

    Cheers,

    – Mahmoud

  109. 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.

    😀

  110. 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.

  111. @ John Hoff

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

  112. 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

  113. 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….

  114. 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

  115. 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.

  116. 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

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

  118. 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”

  119. 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.

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

  121. 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

  122. 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

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

  124. 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-includesgeneral-template.php
    file.

    Thanks so much Matt!!!
    ~ Robert Bury

  125. 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

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

  127. 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).

  128. 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?

  129. 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?

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

  131. 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

  132. 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/

  133. 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?

  134. 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?

  135. 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

  136. 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!

  137. 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?

  138. 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.

  139. 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…

  140. Christian Geek

    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 …

  141. 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.

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

  143. 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.

  144. 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!

  145. 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!

  146. 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?

  147. 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”

  148. 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/

  149. 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?

  150. 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!

css.php