Cloud Platform

Preventive access

Implementing comprehensive security measures involves preventive access to entire domains. It prevents entry for users and bots from specific IP addresses and domains, and restricts access to particular areas within a domain. This page outlines the use cases and suggested code snippets for controlling access to your site using the .htaccess file.

Preventing access to a domain

You can prevent users from accessing a domain or prevent users from a certain domain from accessing your website.

The following are two example use cases of this type of preventative access:

  • Limiting access to a domain by allowing only a specific group of domains or IP addresses.

    #Protect the origin
    <IfModule mod_setenvif.c>
    SetEnvIf Host ^origin\.domain\.com$ origin=1
    SetEnvIf AH_CLIENT_IP ^127\.0\.0\.1$ whitelist=1
    SetEnvIf AH_CLIENT_IP ^10\.171\. whitelist=1
    SetEnvIf AH_CLIENT_IP ^10\.210\.122\.14$ whitelist=1
    SetEnvIf AH_CLIENT_IP ^192\.168\.204\.109$ whitelist=1
    SetEnvIf AH_CLIENT_IP ^192\.168\.236\.194$ whitelist=1
    Order deny,allow
    Deny from env=origin
    Allow from env=whitelist
    </IfModule>
    
    • These IP addresses are for demonstration only.
    • The Deny from line ensures that this snippet only runs or users accessing the site using the origin host.
  • Preventing access to the DNS name of your Elastic Load Balancer (ELB):

    <Limit GET>
     order allow,deny
     allow from all
     deny from [ELB DNS name]
    </Limit>
    

    If you have dedicated balancers, you may achieve this using your VCL (Varnish).

Preventing access to users originating from a domain

Requests to domains can be blocked by referring to the HTTP_REFERER variable as shown in the following example code:

  • For single domains, add the following code to your .htaccess file:

    RewriteCond %{HTTP_REFERER} domain-name\.com [NC]
    RewriteRule .* - [F]
  • For multiple domains, add the following code to your .htaccess file:

    RewriteCond %{HTTP_REFERER} domain-one\.com [NC,OR]
    RewriteCond %{HTTP_REFERER} domain-two\.com [NC,OR]
    RewriteCond %{HTTP_REFERER} domain-three\.com
    RewriteRule .* - [F]
    

Preventing access to specific pages

Some customers may only want specific IPs to be able to log in to the Drupal website. The recommended code snippet to implement this is made with the following considerations:

  • If you are using Varnish, ensure your page caches do not serve restricted content.

    Set max-age to 0. See the max-age headers for specific pages, files, or paths for help in setting max-age=0 in appropriate circumstances. Ensure that the user page is not cached after the accepted IP has accessed the page.

  • Ensure only accepted IPs can access the page by using AH_Client_IP variable. This is needed on Cloud Platform if your website is behind an ELB. This is to ensure that the correct IP is checked in the code.
  • Ensure that Drupal does not cache the user page by adding the following into the websites settings.php:

    if (isset($_GET['q']) && strpos($_GET['q'], 'user') === 0) {
    $conf['cache'] = FALSE;
    

The following is the recommended code snippet for the .htaccess file:

Header always set Cache-Control max-age=0 env=userpage
RewriteCond %{REQUEST_URI} ^/user(/login)*$ [OR]
RewriteCond %{QUERY_STRING} ^q=user(/login)*$
RewriteCond %{ENV:AH_Client_IP} !^2.121.88.122$
RewriteCond %{ENV:AH_Client_IP} !^12.211.9.49$
RewriteCond %{ENV:AH_Client_IP} !^123.45.
RewriteCond %{ENV:AH_SITE_ENVIRONMENT} ^(dev|test|prod)$
RewriteRule ^ http://%{HTTP_HOST} [R=302,L,E=userpage:1]

You can use a similar method to restrict access to a single page to one IP address.

The following code restricts access to /path/to/page to the IP 192.168.2.3:

// Add this to the end of settings.php
// Handle allowlisting for a /path/to/page URL
if ($_SERVER['REQUEST_URI'] == '/path/to/page') {
    // Turn off page caching (internal and external) for this page
    // to avoid a valid IP getting this page into cache.
    drupal_page_is_cacheable(FALSE);

    // Only allow access to an IP.
    if ($_ENV['AH_Client_IP'] != '192.168.2.3') {
        // Deny access
        drupal_add_http_header('Status', '403 Forbidden');
        echo "<h1>403 Forbidden</h1><p>Access is forbidden from " . $_ENV['AH_Client_IP'] .". Shoo!</p>\n\n";
        exit;
    }
}

After this change is implemented, you must clear the Varnish cache for that page.

Preventing core Drupal pages

Files such as CHANGELOG.txt can be used to identify security vulnerabilities in your Drupal installation to a malicious script or user. While there are several ways to identify the version of Drupal, one addition to your .htaccess file file can make it slightly less obvious by adding in the following alias rules:

#various alias rules
Redirect 404 /CHANGELOG.txt
Redirect 404 /COPYRIGHT.txt
Redirect 404 /cron.php
Redirect 404 /INSTALL.mysql.txt
Redirect 404 /INSTALL.pgsql.txt
Redirect 404 /INSTALL.sqlite.txt
Redirect 404 /INSTALL.txt
Redirect 404 /install.php
Redirect 404 /LICENSE.txt
Redirect 404 /MAINTAINERS.txt
Redirect 404 /PATCHES.txt
Redirect 404 /README.txt
Redirect 404 /update.php
Redirect 404 /UPGRADE.txt
Redirect 404 /web.config

Preventing file resources from domains

You may want to prevent a specific directory from being accessed by the general public unless it is being pulled by a particular website. This example blocks requests to the /sites/default/files directory unless the request comes from www?, prod-kb, or the kb subdomains of example.com.

RewriteCond %{REQUEST_URI} ^/sites/default/files
RewriteCond %{HTTP_REFERER} !^http://prod-kb.example.com [NC]
RewriteCond %{HTTP_REFERER} !^http://kb.example.com [NC]
RewriteCond %{HTTP_REFERER} !^http://(www.)?example.com [NC]
RewriteRule .* - [F]

Preventing access to a subfolder

Use the following code to block access to a subfolder:

RewriteCond %{THE_REQUEST} ^A-Z{3,9}\ /(/+)/.*\ HTTP NC
RewriteRule .* - [F,L]

Preventing HTTP methods

You may not want to allow certain types of methods to be processed by your site. This blocks any HTTP request that is not a GET or a POST request.

RewriteCond %{REQUEST_METHOD} !^(GET|POST)
RewriteRule .* - [F]