Forum Moderators: phranque

Message Too Old, No Replies

Doubts regarding .htaccess security tricks for Wordpress

         

dustie

3:33 pm on Dec 13, 2013 (gmt 0)

10+ Year Member



The widely-advertised tricks for securing Wordpress are burdened by the fact that limiting access will simply break certain Wordpress functionality, which is something most tutorials do mention... however, I have worries that most of them would actually stop Wordpress from working at all.


The trick with locking up wp-admin with a password:

AuthName "Admins Only"
AuthUserFile /home/yourdirectory/.htpasswds/public_html/wp-admin/passwd
AuthGroupFile /dev/null
AuthType basic
require user putyourusernamehere
<Files admin-ajax.php>
Order allow,deny
Allow from all
Satisfy any
</Files>


There is an exception for admin-ajax.php, so that some themes/plugins can access the file, right? But isn't the 'Allow from all' part essentially giving access to everyone? admin-ajax.php is a sensitive part of Wordpress, so doesn't allowing everyone to access it past the password lock defeat the purpose?

Isn't there a way to only allow Wordpress to access itself from within my own website, by using the my domain name or host IP with the 'allow from...' instruction? I think that would be safer than just opening up a gate to admin-ajax.php for everybody?
Or, is that how it actually does work, that it only allows access to 'all' who come from within the website, from within my server/host/web account?


AuthUserFile /dev/null
AuthGroupFile /dev/null
AuthName “Access Control”
AuthType Basic
order deny,allow
deny from all
allow from 123.123.123.123


This is supposed to lock the wp-admin from everyone, except the IP listed in 'allow from...', but isn't this going to block the Wordpress install itself from anything in wp-admin? I'm guessing an exception for admin-ajax.php would also be necessary here, again, so that some themes/plugins can access the file? Which would, again, introduce a gate to admin-ajax for everybody out there?...


Another instruction suggests to block script access/execution from within wp-content:

<Files *.php>
Order Allow, Deny
Deny from all
</Files>


Considering how Wordpress works, isn't this going to completely wreck Wordpress, as it won't be able to use any theme and plugins php files?... Or am I missing something here? Are the requests Wordpress makes for its own files when it's running on my host account recognized as some sort of 'inside requests' and are allowed to pass through these deny rules?...


Yet another one, this time blocking the wp-includes directory:

RewriteEngine On
RewriteBase /
RewriteRule ^wp-admin/includes/ - [F,L]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]


The same as above, looks like this will stop Wordpress from wp-includes php files, which seem crucial to its functioning.

There is also the trick to hide wp-config.php from direct access, also using the <Files> brackets and Deny instructions, which looks like it's also going to hide it from Wordpress itself?...


Moreover - all tutorials specify these instructions as the seemingly only necessary ones to be put in a .htaccess file in a given directory (wp-admin, wp-includes, uploads, etc.). But isn't that going to cancel out the main .htaccess file in the web root/Wordpress root directory and any safety instructions set up in them?
I set up hotlinking protection from cPanel on my host to protect image files and it crated a .htaccess file in the web root directory. My Wordpress is in a subdirectory, where another .htaccess was present, created by Wordpress itself, with pretty permalinks instructions. Hotlinking was thus banned around my web account, because of the root .htaccess, but - that protection was lifted in the Wordpress subdirectory, apparently because of the presence of another .htaccess file, which only icluded Rewrite rules for permalinks, and no hotlinking protecton... judging from this, .htaccess files completely overwrite/cancel out each other's functionality?
So if I set up limits on various user agents in root public_html .htaccess, and then place only premalinks rewrites in public_html/wordpress/ .htaccess, these user agents will still be able to access /wordpress, because the limiting instructions won't apply there anymore?


I would appreciate it if someone could help me understand how all this works. I understand how Rewrite rules work and how they can filter/deny requests coming from outside, but I'm still not sure how denying or allowing is dealt with when it comes to activity within a web server/account...

JD_Toims

6:14 pm on Dec 13, 2013 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



[There is an exception for admin-ajax.php, so that some themes/plugins can access the file, right? But isn't the 'Allow from all' part essentially giving access to everyone? admin-ajax.php is a sensitive part of Wordpress, so doesn't allowing everyone to access it past the password lock defeat the purpose?

It likely doesn't "defeat the purpose", because no one who is not logged in would have access to the other PHP [server-side] file(s) they would need to save/manipulate/do anything -- Not 100% sure since I don't work with WP very much.

This is supposed to lock the wp-admin from everyone, except the IP listed in 'allow from...', but isn't this going to block the Wordpress install itself from anything in wp-admin?

No, it won't block WP from doing anything, because the htaccess file is run for http requests, but will not affect a script using the internal file system. Basically, if WP used "include 'http://example.com/admin/some-file.ext'" rather than "include $_SERVER['DOCUMENT_ROOT'].'/admin/some-file.ext'" you would be correct.

Considering how Wordpress works, isn't this going to completely wreck Wordpress, as it won't be able to use any theme and plugins php files?... Or am I missing something here? Are the requests Wordpress makes for its own files when it's running on my host account recognized as some sort of 'inside requests' and are allowed to pass through these deny rules?

See the answer above.

judging from this, .htaccess files completely overwrite/cancel out each other's functionality?

You can add the following on the line immediately after RewriteEngine on in the sub-directory files: RewriteOptions Inherit if you would like to have the "higher level" file(s) also applied, but that said, it's better and easier to manage/maintain if you just use the root file and apply whatever specific rulesets you need to specific directories.

BTW: Welcome to WebmasterWorld!

[edited by: JD_Toims at 6:23 pm (utc) on Dec 13, 2013]

lucy24

6:17 pm on Dec 13, 2013 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I started to say
Those are some damn good questions but they require more time than anyone has had in the past three hours. (I, for example, was supposed to have been somewhere almost half an hour ago :()

and then Justin zipped in with a preliminary reply. There will be more to follow.

JD_Toims

6:29 pm on Dec 13, 2013 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



LOL Yeah, I actually saw it a couple hours ago and didn't have time, but then a download I need to work on decided it needs to keep stalling out for some reason, so I came back to it for a bit of headache relief.

dustie

6:48 pm on Dec 13, 2013 (gmt 0)

10+ Year Member



Thank you!


I see it now, thanks for clearing this up.

In this case however, which themes or plugins can I expect to run into trouble with accessing files when I apply those protection examples I brought up? I'll be trying to keep plugins on my website to absolute minimum: social media, ads plugin, page numbering and that's about it I think. I know I will be using cron jobs with wp-cron.php in my site too, which I suppose might also require an exempt from .htaccess protection in order to function normally...

As for the subdirectories .htaccess, how do I apply password protection instructions to wp-admin (or other protections to other subdirectiories) directly in the root .htaccess?

Most tutorial only instruct to put certain commands in subdirectories' .htaccess files, but I would think it's better to have the general .htaccess protection combine with the subdirectory protection, as opposed to having only either of them work at the same time...

lucy24

1:50 am on Dec 14, 2013 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Since you can't have <Directory> sections in htaccess, you pretty well have to have more than one htaccess file. The one huge exception is mod_rewrite: You should do everything in your power to put all RewriteRules into the same htaccess. They're not inherited the way almost everything else in apache is, and even if you do say "RewriteOptions inherit", the inherited rules are applied after any new rules.

Anything else-- access control, auto-indexing, special caching rules, et cetera et cetera-- goes in htaccess for the directory it pertains to.

You should work on the assumption that every time you add or change something, such as a theme or plugin, your htaccess file will be affected. So always keep a local copy of your htaccess file, and check for changes every time you've done anything to the site. Make sure any RewriteRules continue to be in the right order, and that nothing conflicts with anything else.

htaccess files made for CMS use tend to be pretty dreadful, in part because everything is utterly generic. For example, the first thing you'll want to do is get rid of any <IfModule... envelopes. Not their contents! Just the envelope itself. For any given mod, you've either got it or you haven't. (There are simple ways to find out, even if your host won't say.) In the particular case of mod_rewrite: if you haven't got it, the CMS simply won't work.

g1smd

1:00 am on Dec 17, 2013 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



On the flags in the code, change [F,L] to [F].

lucy24

1:45 am on Dec 17, 2013 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Basically, if WP used "include 'http://example.com/admin/some-file.ext'" rather than "include $_SERVER['DOCUMENT_ROOT'].'/admin/some-file.ext'" you would be correct.

Alternatively you could add the [NS] flag. In fact, include files (SSI) are the specific example given in the docs for this flag. Saves a nanosecond or two because then the server doesn't have to evaluate any Conditions.

g1smd

1:37 pm on Dec 17, 2013 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Includes, being an internal file-system process, should not have protocol and hostname included.

You do not usually want to fetch the file over HTTP.

lucy24

9:56 pm on Dec 17, 2013 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Here I was thinking purely about what do do in htaccess if the page code is treated as unchangeable. If you have a choice between [NS] and an added condition in an otherwise identical RewriteRule, go with [NS].

dustie

2:40 am on Dec 20, 2013 (gmt 0)

10+ Year Member



I'm a bit lost with the flags issue, I'll look them up again to remember what they're all for, but in the meantime - why drop the L flag?

lucy24

4:33 am on Dec 20, 2013 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



why drop the L flag?

Purely because it's redundant. Other than that it makes no difference.

F implies L.
G implies L.
P and PT both imply L. (Careful! All RewriteRules in htaccess carry an implied PT-- but this does not imply L.)

R does not imply L, although 99 times out of 100 you will use both.

I have never personally seen a RewriteRule leading to [R] without [L]. g1 or someone like him may be able to point to an example.