Block some Drupal URLs - drupal

Is there a module I can use to disable some Drupal system pages? For example, I'd like to disable node, taxonomy/term/*, filter/tips.

I'm not sure if there is a module that does that, but it's not too hard to write your own custom module for this. You only need to implement hook_menu_alter (and clear the cache after changing your code). You can choose to return an 'access denied' page or a '404 not found':
<?php
function MODULENAME_menu_alter(&$items) {
// This will deny access to taxonomy/term/* for all users.
$items['taxonomy/term/%']['access callback'] = FALSE;
// This will completely remove filter/tips, resulting in a 404.
unset($items['filter/tips']);
}
?>
If you want to know more about writing Drupal modules, see http://drupal.org/developing/modules.

This seems to be more of a "one time" configuration to me. So I wonder if its necessary to have an admin interface for this that you have requested in one of your comments.
If you're using apache, in the virtual host configuration of your site you can include the following directives:
<LocationMatch ^/taxonomy/term>
SetHandler server-status
Order Deny,Allow
Deny from all
</LocationMatch>
<LocationMatch ^/filter/tips>
SetHandler server-status
Order Deny,Allow
Deny from all
</LocationMatch>
This will deny access to those URLs. But you need to make sure that you don't have an URL aliased to taxonomy/term/ etc paths. Otherwise the user can access those URLs.
Check http://httpd.apache.org/docs/2.0/mod/core.html#locationmatch
and http://httpd.apache.org/docs/2.0/mod/core.html#location for some documentation

Related

How to prevent users to access wp admin and wp-login.php?

I want restrict all users to access WordPress website login.
For example: Suppose I have WordPress website domain example1.com and I want to restrict all users to access admin login with example1.com/wp-admin and example1.com/wp-login.php.
When any user hits these url it redirect to restrict_user page and also I want to access wordpress login page with example1.com/user_login instead of hit example1.com/wp-admin and example1.com/wp-login.php urls.
And please suggest me how can i make my WordPress website more secure from hacking?
You can lock down the wp-admin page with htaccess deny all and hen setting an allowed ip.
order deny,allow
deny from all
allow from 127.0.0.1
You can also set a htpasswd file with allowed logins and password protect the page. I would also make sure your username in wp-admin is not something easy like 'admin' or 'editor'.
<IfModule mod_auth.c>
AuthUserFile /home/path/.htpasswd
AuthName "Username and password required"
AuthType Basic
<Limit GET POST>
Require valid-user
</Limit>
</IfModule>
Furthermore i would highly recommend wordfence as a good plugin for protection from hacks etc.
Restricting access to wp-admin directory
Apache 2.4+
Add this snippet to your .htaccess file, created in wp-admin directory:
<RequireAny>
Require ip 64.176.174.0/255.255.255.0
Require ip 64.176.176.0/255.255.255.0
</RequireAny>
and add as many IP Address/Subnet Mask pairs, as you wish, regarding the client IP address you would like to have access to admin area. I have added two samples above.
Apache 2.4-
Add this snippet to your .htaccess file, created in wp-admin directory:
<Directory>
Order Deny,Allow
Deny from all
Allow from 64.176.174.0/255.255.255.0
</Directory>
Restricting access to wp-login.php path
Add this snippet to you current theme's functions.php file:
function my_checkRole(){
if( !( current_user_can( 'administrator' ) ) && !( defined('DOING_AJAX') && DOING_AJAX ) ){
wp_redirect( site_url( 'restrict_user' ) );
exit;
}
}
add_action( 'admin_init', 'my_checkRole' );
Changing the wp-admin path
It is possible to change it, but why do you think that has any value at all? You cannot hide anything from a Bot - that is just not possible to do.
Hackers use automated Bot programs to find whatever they want to find.
A good approach is Action Approach:
hacker X does bad action Y and the result is Z = Forbidden.
So just use the presented method in Restricting access to wp-login.php path section and that will be OK.
From nginx, using php7.0-fpm on Ubuntu 16.04LTS.
My base configuration I modified from:
https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-in-ubuntu-16-04
I found a bunch of configs online that tried to combine wp-login.php and wp-admin into the same rule, but allowed wp-login.php to be raw downloadable!
Granted, its a generic Wordpress file, but that is dangerous behaviour.
I've separated the rules, since wp-admin is a folder, anything accessed within will follow generic rules for images/php/etc. For wp-login.php I wanted to specifically replicate php execution. I've allows full internal network access to 10.x.x.x.
location ~ wp-login\.php {
allow 10.0.0.0/8
deny all;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location /wp-admin/ {
allow 10.0.0.0/8
deny all;
index index.php index.html index.htm;
try_files $uri $uri/ /index.php?$args;
}

Why can't I block access to files with .htaccess ( order not allowed here)?

I've tried everything. I read other how to threads here and elsewhere. I have the following in my apache2 site configuration file:
<Directory /var/www/html/site_root/>
AllowOverride All
</Directory>
</VirtualHost>
There is no other occurence of "AllowOverride" in the site conf file so it's not a case of something earlier in the file overriding this (don't even know if that's possible). I also tried '/var/www/html/site_root'.
If I try either of the following (or both) in my /var/www/html/site_root/.htaccess file:
<Files .htaccess>
Order Allow,Deny
Deny from all
</Files>
<Files "xmlrpc.php">
Order Allow,Deny
Deny from all
</Files>
I get 520s and the whole site is crashed. I also tried /xmlrpc.php or "xmlrpc.php" without "" and ./xmlrpc.php etc. No matter what I do my error log is full of:
[Thu Dec 03 18:05:25.628237 2015] [core:alert] [pid 6956] [client 192.168.0.1:56529] /var/www/html/site_root/.htaccess: order not allowed here
How can this be and why is this so difficult to do?
My purpose is to block access to /xmlrpc.php. This is an absolute Achilles heel for WordPress. It is very easy to crash and burn any site by just hitting this over and over and over again. For some reason WordPress leaves it wide open by default and Cloudflare is not able to detect or protect against these attacks. They happen all the time and it brings down the server completely.
Thanks.
The best answer I found is this:
If your server is an Apache, you can block access before WordPress is even reached with one line in your .htaccess:
Redirect 403 /xmlrpc.php
You can add another line to keep the response short:
ErrorDocument 403 "die"
That will send a very minimal response (three bytes plus HTTP headers), and it will save your resources for better traffic.
Source:
https://wordpress.stackexchange.com/questions/156522/restrict-access-to-xmlrpc-php
Please go vote up the answer at the wordpress stack, by user #toscho. I don't have enough reputation. Toscho's answer is is way better than the accepted answer because you can deny access in .htaccess and still burn up server resources loading the 404 in Wordpress. His answer actually saves you one byte over mine.
Well did you restart your server after you made changes to apache2.config? Secondly there is a difference between order allow,deny AND order deny,allow
Try using this
<Files xmlrpc.php>
order deny,allow
deny from all
</Files>
You can also disable the XML-RPC Feature, from the system itself. Just put this in your wp-config
add_filter('xmlrpc_enabled', '__return_false');
Update: Some clarification:
I agree with jason, blocking xmlrpc.php at the htaccess level is always a much better idea because even if you disable it through the filter, the site still goes through the whole request cycle. Here filters is just being used as a safeguard from someone getting in, but the site is still open to DDOS attacks. In short usage of filters is only for people who are using it for some other purposes and not finding an escape from DDOS attacks, for eg if someone doesn't have access to the htaccess file.

Apache 2.4 Require ip not working

Trying to go from older allow, deny, order syntax to the new one to secure WordPress admin section, but I can't get it to recognize my IP.
This is what my .htaccess file contains in /wp-admin folder.
ErrorDocument 401 default
ErrorDocument 403 default
# Disallow access for everyone except these IPs
<RequireAny>
Require ip 50.153.218.4
</RequireAny>
# Allow plugin access to admin-ajax.php around password protection
<Files admin-ajax.php>
<RequireAll>
Require all granted
</RequireAll>
</Files>
And this is what I have in .htaccess in the root under the WordPress mod rewrite info.
# Protect WordPress
ErrorDocument 401 default
ErrorDocument 403 default
<Files wp-login.php>
<RequireAny>
Require ip 50.153.218.4
</RequireAny>
</Files>
But I just keep getting 403 Forbidden error. When I add Require All Granted under the IP, it works fine, but that opens it up to every user. It seems like apache is just not reading my ip correctly? Anyone have any idea what I'm doing wrong?
Your syntax looks perfectly fine to me.
The only reason I can think that apache might not be reading the user's IP correctly is if you're behind a proxy or load balancer. If that is the case you would use X-Forwarded-For instead of ip. In PHP, you can confirm if you're behind a proxy by comparing $_SERVER['REMOTE_ADDR'] and $_SERVER['HTTP_X_FORWARDED_FOR'].
If that is not the issue so you might have better luck finding an answer at ServerFault.
I can offer you some workarounds though. The easiest solution may be to use one of several WordPress security plugins that allow you to restrict access to the backend by IP address.
Alternatively, in your theme or in a plugin you can implement this same sort of authentication logic:
add_action('init', function() {
$allowed_ips = array('50.153.218.4');
if(is_admin() || $GLOBALS['pagenow'] == 'wp-login.php') {
if( !DOING_AJAX && !in_array($_SERVER['REMOTE_ADDR'], $allowed_ips) ) {
wp_die('', 'Forbidden' array(
'response' => 403
));
}
}
});
Update: From the comments it looks like there is a proxy involved. This should work:
ErrorDocument 401 default
ErrorDocument 403 default
SetEnvIF X-Forwarded-For "50.153.218.4" AllowIP
# Disallow access for everyone except these IPs
<RequireAny>
Require env AllowIP
</RequireAny>
# Allow plugin access to admin-ajax.php around password protection
<Files admin-ajax.php>
<RequireAll>
Require all granted
</RequireAll>
</Files>
and
# Protect WordPress
ErrorDocument 401 default
ErrorDocument 403 default
SetEnvIF X-Forwarded-For "50.153.218.4" AllowIP
<Files wp-login.php>
<RequireAny>
Require env AllowIP
</RequireAny>
</Files>
You should also be able to use a similar method using the "Allow, Deny" syntax.

Allow Timthumb to work in a htpasswd protected Wordpress

I have a domain I use for development purposes. In this domain I have several subdirectories with different wordpress installations.
To hide the whole area I made a simple htpasswd protection in the root.
Now I have one of this Wordpress in the domain that uses timthumb library to resize images, and due to the htpasswd, I get "NetworkError: 400 Bad Request" instead of the image.
This is an example of the request that gets the error
http://subdomain.domain.com/WP/wp-content/plugins/plugin-directory/timthumb.php?src=http%3A%2F%2Fsubdomain.domain.com%2FWP%2Fwp-content%2Fuploads%2F2015%2F01%2F012015_valentines_hp_budvase.jpg&w=300&h=620&zc=1
Is there a way to bypass the protection only for that file?
More details on my paths to better read my .htaccess snippets:
I'm in a subdomain pointed to a subdirectory called 'subdomain_folder'
.htaccess I'm working on is located in 'subdomain_folder'
WP is in a subdirectory called 'WP' inside 'subdomain_folder'
Complete Path to WP: '/home/some-folder/public_html/subdomain_folder/WP
Complete Path to Uploads: '/home/some-folder/public_html/subdomain_folder/WP/wp-content/uploads
I tried this:
SetEnvIf Request_URI "^/WP/wp-content/plugins/plugin-dir/timthumb\.php$" allow
AuthType Basic
AuthName "Restricted Area"
AuthUserFile "/home/some-folder/.htpasswds/public_html/subdomain_folder/passwd"
Require valid-user
Order allow,deny
Allow from env=allow
Satisfy any
UPDATE
Someone adviced me that allowing access to timthumb.php file it's pointless, instead I should allow him to make http requests, or allow full access to uploads folders so, I tried the following, allowing requests from localhost ip
AuthType Basic
AuthName "Reserverd Area"
AuthUserFile "/home/some-folder/.htpasswds/public_html/subdomain_folder/passwd"
Require valid-user
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
Satisfy Any
Tried both localhost and 127.0.0.1
I even tried to add another .htaccess in the single WP upload folder (where timthumb asks for images) with rule to allow from any
Satisfy Any
Order Allow,Deny
Allow from all
Still I cant' get images shown, and I keep getting the NetworkError: 400 Bad Request" instead of the image.
Last Detail, the .htaccess in the WP directory is a standard wp htaccess --> pastebin.com/8PRqEYQ2
I Found the solution.
The right way is indeed allowing requests from the server itself, but the localhost IP (127.0.0.1) was not the right adress to allow.
I made a Reverse IP Lookup searching for the domain I'm on, and I used that IP.
This is the .htaccess that works
RewriteEngine On
<IfModule mod_authn_file.c>
AuthName "Restricted Area"
AuthUserFile "/home/path-to-passfile/passwd"
AuthType Basic
Require valid-user
Order Deny,Allow
Deny from all
# Use your server ip:
Allow from 111.111.111.11
Satisfy Any
</IfModule>
With this rules I can develop apps using timthumb.php in .htpasswd protected directory.
Criticisms and improvements are welcome :)

Override All Wordpress htaccess on server

We've tried a few things that we found around Google for this, but can't seem to get anything to work.
The Problem
We have a server with around 500 Wordpress websites on it. We're trying to lock down all the wp-login.php pages for every instance to the IP address of our office using a global htaccess - but the individual Wordpress htaccess files are overriding this.
The Environment
We're hosted on an AWS Linux server running Plesk to manage each website / Wordpress instance.
The Question
Is there a way we can set one htaccess file on the server to lock down all of the Wordpress login pages without the individual htaccess files overriding this?
any help or suggestions for a good way to do this, would be appreciated.
Thanks in advance
I assume that you have read up on the RewriteOptions directive. As I explain in Tips for debugging .htaccess rewrite rules and as you have found with WP which generates its own .htaccess files, by default the current path is scanned for .htaccess and the rewrite rules in the lowest are applied unless a higher one specifies a RewriteOptions Inherit in which case it's rules are executed after rules specified in the child scope, and this is the catch-22 in that WP access file generates a [L] flag on all its execution paths preventing the parent rules from firing.
So the answer is to do this with an Apache mechanism other than rewrite and you can use the SetEnvIf directive:
SetEnvIf Remote_Addr "!^192\.168\." forbidden
<Files *>
Order allow,deny
Allow from all
Deny from env=forbidden
</Files>
or
SetEnvIf Remote_Addr "!^192\.168\." forbidden
<Directory /var/www/wproot>
Order allow,deny
Allow from all
Deny from env=forbidden
</Directory>
Clearly you'll need to change the Regexp to your local needs but this should do the biz. The Apache docs give other variants on this, but you should be able to find one which works in your case. Just put this in the a per-virtual server context -- within a Directory(Match) directive if necessary -- or in a common parent directory .htaccess file.
I ended up getting this to work with your first suggestion, but actually without the SetEnvIf line being required, so thanks very much! this was my .htaccess in the /var/www/vhosts folder for anyone else needing this:
<files wp-login.php>
order deny,allow
deny from all
Allow from xxx.xxx.xxx.xxx
</files>
Nice and simple and completely different from the previous routes I was trying to take for this.

Resources