Password protecting the wp-admin directory

Several places recommend to block the WordPress admin area with a password. While this certainly is a good idea, implementing it properly is non-trivial.

One of the problems is that the WordPress Ajax handler script is located in the admin directory. So password-protecting the admin area will break all Ajax functionality your blog might be using on the frontend.

First, see this tutorial on how to password protect directories with an .htaccess file. Sivel has an example for whitelisting the Ajax handler, add these line to your .htaccess file:

# These are the lines that do the password protection.
# You probably already created them while reading through the tutorial linked above.
AuthUserFile /path/to/your/htpasswd
AuthType basic
AuthName "Restricted Resource"
require valid-user# This is the whitelisting of the ajax handler
<Files admin-ajax.php>
    Order allow,deny
    Allow from all
    Satisfy any 
</Files>

Please notice that you absolutely need to create the htpasswd file, see the linked tutorial above.

Update: /wp-admin/css/install.css is also sometimes needed on the frontend, you should whitelist that as well.Here's the necessary configuration to whitelist a file in a password protected location in lighttpd:

$HTTP["url"] =~ "^\/wp-admin\/.*" {
    $HTTP["url"] !~ "^\/wp-admin\/(admin-ajax\.php|css\/.*)" {
        auth.require = (
            "" => (
                "method" => "basic",
                "realm" => "Password protected area",
                "require" => "user=theuser",
            ),
        ),
    },
},
Published on June 14, 2010 at 3:16 p.m. by Nicolas and tagged jQuery, WordPress, ajax, howto, security, apache, lighttpd. You can follow the discussion with the comment feed for this post.

28 comments

  • avatar
    Anders Vinther wrote this comment on Sept. 23, 2010, 3:15 p.m.
    Great stuff... So to whitelist /wp-admin/css/install.css also would the correct syntax be: or ? Thanks, Anders
    Reply to this comment
  • avatar
    Dirkjan wrote this comment on Sept. 26, 2010, 10:09 a.m.
    Starting lighttpd: parsing regex failed: ^\/wp-admin\/(admin-ajax\.php|css\/install\.css -&gt; missing ) at offset 47 I added a ) between 'css' and '"'
    Reply to this comment
  • avatar
    Ryan Ash wrote this comment on Oct. 11, 2010, 4:31 a.m.
    Okay, I'm a newbie at this. I'm trying to figure it out. I whitelisted the admin-ajax.php file yesterday and it worked fine. Today I just get a 404 error. I'm a little unsure of what to do now. I tried a couple of things trying to whitelist the css/install.css with no success. Help!
    Reply to this comment
  • avatar
    Justin Zimmerman wrote this comment on Jan. 25, 2011, 1:40 p.m.
    I've been researching WP security for the last few days, as a new developer, going setting all of the above up to secure my wp-admin is going to take me a day or so to understand, test, and configure... I found this plugin and wondering what you're thoughts are on it? http://www.askapache.com/wordpress/htaccess-password-protect.html Thank you for the review. If the plugin is "passes" it might be a great tools to speed up the process for others.
    Reply to this comment
    • avatar
      nicolas wrote this comment on Jan. 25, 2011, 2:33 p.m.
      I wouldn't recommend to use that, see also http://codex.wordpress.org/Hardening_WordPress#Resources
      Reply to this comment
  • avatar
    Justin Zimmerman wrote this comment on Jan. 25, 2011, 2:44 p.m.
    Thanks Nicolas. Majority of the posts were about people being locked out of wp-admin. If I wanted to hire you to help me setup my wp-admin protection, what would I expect to pay you for your service? Could you also teach me via my webinar account how to do it myself?
    Reply to this comment
  • avatar
    Justin Zimmerman wrote this comment on Jan. 25, 2011, 2:59 p.m.
    I also found this... what's the flaw if any in following this advice? http://www.squidoo.com/wordpress_security#module63921672
    Reply to this comment
    • avatar
      Andrew Diamond wrote this comment on Feb. 22, 2011, 5:33 p.m.
      I reviewed the steps they suggested on this squidoo page and I've seen them before in the WordPress forums. All of these steps make sense to me except the search robots one. Wouldn't you want a search robot browsing your site caching data, or did I misunderstand what they want you to do here?
      Reply to this comment
      • avatar
        nicolas wrote this comment on Feb. 23, 2011, 3:03 p.m.
        In the best case the cache would have the same content as the site. And you don't visitors from search engines to access cache files, you want them on your site. So disallowing indexing makes sense.
        Reply to this comment
  • avatar
    Andrew Diamond wrote this comment on Feb. 21, 2011, 4:03 p.m.
    Hello Nicolas, I put in my .htaccess password protection as you recommended, and now when I go to my wp-admin dashboard I get a "Page not found." When I disable the .htaccess, dashboard loads fine. Any thoughts?
    Reply to this comment
    • avatar
      nicolas wrote this comment on Feb. 21, 2011, 7:41 p.m.
      Hm, not really. Check the webserver's error log?
      Reply to this comment
      • avatar
        Andrew Diamond wrote this comment on Feb. 22, 2011, 5:29 p.m.
        I guess I should have done that from the get-go. I had contacted my hosting providers support at the same time, and they resolved the issue for me. I use HostGator, so I'm not sure if everyone would run into this issue or not, but I was explained that WordPress rewrites do not work on password protected directories. I was given two lines of code to put in my .htaccess file: 'ErrorDocument 401 /%{REQUEST_URI}/myerror.html ErrorDocument 403 /%{REQUEST_URI}/myerror.html' After that, it now requires my user name and password as intended! :) Andy
        Reply to this comment
        • avatar
          Doug wrote this comment on Aug. 24, 2011, 4:03 p.m.
          Brilliant! I couldn't get the whitelisting to work at all, but adding just those two ErrorDocument lines (I removed the whitelisting stuff) to my .htaccess cleared up the redirect to the 404 Page Not Found error.

          Just to note: I'm not on HostGator, and I didn't even bother to create the myerror.html page, and it still worked. Now I can log into the /wp-admin directory again with the added layer of security provided by htaccess password-protection. :)
          Reply to this comment
  • avatar
    Hari Karam Singh wrote this comment on Dec. 1, 2011, 5:02 p.m.
    What about `/wp-admin/load-scripts.php`? Whilst rooting around WP code I noticed some constants which I believe might allow the same script compression in the front-end which the back-end enjoys: `COMPRESS_SCRIPTS`, `CONCATENATE_SCRIPTS`, etc. (see script-loader.php, particularly `_print_scripts()`)

    I haven't played around with them or the undocumented(?) WP_CACHE but thought I should at least put the flag up in case anyone had any strange problems...
    Reply to this comment
    • avatar
      Nicolas Kuttler wrote this comment on Dec. 1, 2011, 5:36 p.m.
      I think you're right. But afaik the script loader is only used in the admin by default. There may be a few plugins out there that use it though. So yes, you might want to whitelist the loader as well if you use such a plugin.

      Aaaah, the usual wp mess :-)
      Reply to this comment
  • avatar
    xxx wrote this comment on Dec. 17, 2011, 1 p.m.
    So yes, you might want to whitelist the loader as well if you use such a plugin.
    Reply to this comment
  • avatar
    LunaTech wrote this comment on March 7, 2012, 10:48 a.m.
    Nicolas. I really appreciate your work on this issue and it seems to be very thorough with links answering questions regarding the subject. Since I'm a novice at htaccess I would like you to answer this question.
    I'm on a shared hosting account with Go Daddy. There is no way to access a folder above my shared accounts root folder. I have contacted them about adding the additional lay of protection to the wp-admin file but all I get back is that the directory is already protected and adding the additional layer of protection is not available on this file.

    Now this might be poor customer service or some server configuration that they are not willing to expound upon, but I think I can get this done.

    I've created a htpasswd file and added directive to the htaccess file. The article you link to states that the htpasswd file should be placed above the root directory on the server. That is not possible on a shared account with Go Daddy. Can I use file permissions to lock down the password file? Can I lock down this directory further given the shared hosting or do I have to upgrade to a dedicated server to allow for additional security measures such as this technique?
    Thank you for this article. It is the most thorough article I've found on this subject.
    Reply to this comment
    • avatar
      Nicolas Kuttler wrote this comment on March 7, 2012, 8:40 p.m.
      To protect the wp-admin directory you create the .htaccess file in it's parent directory, that means the wordpress root directory. You don't need access to anything above to protect wp-admin. Maybe I misread you though? It's getting late here..
      Reply to this comment

Start a new thread

Cancel reply
Markdown. Syntax highlighting with <code lang="php"><?php echo "Hello, world!"; ?></code> etc.