This is the third and last part to our WordPress website security guide. This section, covers .htaccess firewalls.

Most Comprehensive WordPress Security Guide-Part 3/3

WordPress Security Guide Part 3

The .htaccess file often contains a section delimited by # BEGIN WordPress and # END WordPress. This section is maintained by WordPress itself, and it’s a good idea not to modify anything between these tags because they can be overwritten by WordPress updates or permalink structure changes.

For custom rules, you should add them either above the # BEGIN WordPress line or below the # END WordPress line to ensure they remain intact.

.htaccess FireWall Implementation

Here are some Apache .htaccess code snippets that can be employed to implement a robust lightweight Firewall in .htaccess for your security measures.

Both An .htaccess firewalls and Web Application Firewalls (WAFs) like the ones offered by Cloudflare serve to protect websites from malicious traffic. However, they operate at different levels, have distinct capabilities, and are suited for different purposes. Here are the primary differences:

1. Operating Level:
 .htaccess: This is a configuration file used on web servers running the Apache Web Server software. The configurations in this file are applied at the level of the web server itself.

Cloudflare’s WAF: Cloudflare operates as a reverse proxy, which means that traffic to your website goes through Cloudflare’s network before reaching your web server. The WAF works at this network level, examining and filtering traffic before it reaches your server.

2. Capabilities:
.htaccess: Through .htaccess, you can control access based on IP addresses, referrers, block bots, redirect traffic, and more. However, its capabilities are relatively basic compared to a dedicated WAF.

Cloudflare’s WAF: This offers advanced protection against a broader range of web application vulnerabilities, such as SQL injection, Cross-Site Scripting (XSS), and more. It also comes with regularly updated rule sets to protect against known vulnerabilities and zero-day attacks.

While there might be some overlap in the functionalities they offer, .htaccess firewalls and WAFs like Cloudflare’s are not the same. For comprehensive security, using a dedicated WAF like Cloudflare’s in conjunction with server-level configurations like .htaccess rules can provide comprehensive protection.

Block proxy servers

Purpose of the Proxy Firewall:
  • Detecting Proxies: The primary goal is to detect and block traffic coming through proxy servers. Proxies can be used maliciously to hide an attacker’s origin, making them harder to track or block.
  • Limiting Spam and Attacks: By blocking certain proxy traffic, you can potentially reduce spam, brute force attacks, or other malicious activities that are often routed through proxies.
Things to be Aware of:
  1. Legitimate Proxy Users: Not all users who connect through proxies have malicious intentions. Corporate networks, for example, often route their traffic through proxies. Blocking all such traffic can lead to false positives and potentially alienate genuine visitors or customers.
  2. Performance: Always monitor the performance of your website. Adding rules to your .htaccess file might have a slight impact, though this firewall is relatively lightweight.
  3. Order of Rules: The order of rules in an .htaccess file matters. Ensure that these rules don’t conflict with other existing rules or unintentionally override them.
  4. Maintenance: Headers and tactics used by malicious actors evolve. Regularly update and maintain your rules to stay ahead.
  5. Conflicts with Plugins: Some plugins or applications might not work correctly if certain legitimate proxy requests are blocked. Always test thoroughly after implementing changes.
  6. False Positives: Monitor your server logs for 403 Forbidden errors. If you notice a spike in these errors or receive complaints from legitimate users, you might need to adjust your rules.

In summary, while an .htaccess proxy firewall can be an effective way to enhance your site’s security, it’s crucial to implement it carefully and monitor its impact to ensure a balance between security and user accessibility.


1 Blocking proxies using .htaccess firewall

One of the most effective and easy  ways of blocking a significant large amount of proxy visits is to apply a simple firewall.

Apache’s mod_rewrite enables us to evaluate requests for signs of proxy behavior. By setting up rewrite-conditions for commonly used proxy response-headers. It’s possible to filter out much of the “lower-level” proxy noise.

Please be aware, it won’t block everything, especially the “higher-level” or more sophisticated proxies services. (However, compared to blacklisting proxies numbering in the hundreds of thousands, by domain-name or IP-address, this solution is extremely light weight and very effective.)

<IfModule mod_rewrite.c> 
RewriteCond %{HTTP:VIA} !^$ [OR] 
RewriteCond %{HTTP:FORWARDED} !^$ [OR] 
RewriteCond %{HTTP:FORWARDED-FOR} !^$ [OR] 
RewriteCond %{HTTP:X-FORWARDED} !^$ [OR] 
RewriteCond %{HTTP:X_FORWARDED_FOR} !^$ [OR] 
RewriteCond %{HTTP:PROXY_CONNECTION} !^$ [OR] 
RewriteCond %{HTTP:HTTP_PC_REMOTE_ADDR} !^$ [OR] 
RewriteCond %{HTTP:HTTP_CLIENT_IP} !^$ [OR] 
RewriteCond %{HTTP:USERAGENT_VIA} !^$ 
RewriteRule .* - [F] 

1.1 Allow only specific proxies By Domain Name

If you want to allow access to your website via proxies, but only for specific domain names, you can modify the .htaccess rule using the RewriteCond directive.

Here’s an example of allowing proxies only for visitors coming from domains alloweddomain1.com and alloweddomain2.com:

<IfModule mod_rewrite.c>
RewriteEngine On
# Check for proxy headers
RewriteCond %{HTTP:VIA} !^$ [OR]
RewriteCond %{HTTP:FORWARDED} !^$ [OR]
RewriteCond %{HTTP:USERAGENT_VIA} !^$ [OR]
RewriteCond %{HTTP:X_FORWARDED_FOR} !^$ [OR]
RewriteCond %{HTTP:HTTP_PC_REMOTE_ADDR} !^$ [OR]
RewriteCond %{HTTP:HTTP_CLIENT_IP} !^$
# Exclude allowed domains from the block
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?alloweddomain1.com [NC,OR]
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?alloweddomain2.com [NC]
RewriteRule .* - [F]

Ensure that your Apache server is set up to read and obey the .htaccess file. The AllowOverride directive should be set to All or at least FileInfo for the directory in your Apache configuration.

2 Allow Access Only via a Specific Proxy by IP Address

<Directory "/path/to/your/directory">
    # Deny access to everyone
    Require all denied
    # Allow access only from a specific proxy IP address
    Require ip 123.456.789.012

Replace IP_ADDRESS_OF_PROXY with the IP address of your proxy or CDN. This allows access only from that IP and denies from all others.

3 Blocking By IP Address

# Block specific IP addresses
    Require all granted
    Require not ip 123.456.789.012
    Require not ip 234.567.890.123

When placed in the root directory’s .htaccess file, this code will block all requests coming from that specific IP address. With that code in place, it’s easy to block additional IPs:

4 Denying and allowing based on CIDR number

Denying and allowing based on CIDR number

CIDR (Classless Inter-Domain Routing): CIDR is a method used to allocate IP addresses and route IP packets in a more flexible and efficient manner than with the older class-based IP address assignment. In CIDR, an IP address is represented with a slash (“/”) followed by a subnet mask length (a number). This number indicates how many of the first bits of the address specify the network. The rest of the bits specify the host.

For example, in the CIDR notation, the /24 indicates that the first 24 bits (3 bytes) are the network part of the address, leaving the remaining 8 bits (1 byte) for host addresses within that network.

CIDR helps reduce the number of routing table entries and allows for more granular control over IP address assignments, which is especially important given the limited number of IPv4 addresses available.

Using CIDR to block ensures that every variant of the offending IP is restricted from accessing your website.

4.1 Example of blocking based on CIDR:

    Require all granted
    Require not ip
    Require not ip

4.2 Example of allowing/whitelisting based on CIDR:

    Require ip
    Require ip

4.3 Denying and allowing based on wildcard IP-values

In web server management, particularly with Apache, controlling access via IP addresses is crucial. Using wildcard IP values enables administrators to manage access across broad IP ranges without listing each address. This is beneficial for blocking harmful traffic or allowing particular networks.

4.4 Allow Based on Wildcard IP Values

For instance, if you wanted to allow all IPs in the range 123.456.789.*, you would use the CIDR notation 123.456.789.0/24.

Here’s how you can set it up in .htaccess:

# Allow access based on CIDR notation for the IP range
Require ip 123.456.789.0/24
Replace 123.456.789.0/24 with the actual CIDR notation that represents the IP range you want to allow.

4.5 Deny Based on Wildcard IP Values

    Require all granted
    Require not ip 123.456.789.0/24

4.6 Sending blocked IPs to a custom page

  1. Create a custom error page, say blocked.html, and place it in your server’s root or appropriate directory.
  2. Add the following configuration in your .htaccess file or in the server/virtual host configuration:

<IfModule mod_rewrite.c>
    RewriteEngine On
    # List of blocked IP addresses
    RewriteCond %{REMOTE_ADDR} ^123\.456\.789\.0$
    RewriteCond %{REMOTE_ADDR} ^987\.654\.321\.0$
    # Redirect blocked IPs to the custom error page
    RewriteRule ^.*$ /blocked.html [L]

Replace the IP addresses 123.456.789.0 and 987.654.321.0 with the IPs you want to block. You can add more RewriteCond lines as needed for additional IPs.

Make sure you test these changes in a controlled environment before applying them to a live server to ensure there are no unexpected behaviors.

4.7 Block a partial-domain via network/netmask values

    Require all granted
    Require not ip

5 Block domain.com but allow subdomain.domain.com

# Block domain.com
RewriteCond %{HTTP_HOST} ^domain\.com$ [NC]
RewriteRule .* - [F]
# Allow subdomain.domain.com (this rule isn't strictly necessary as the block only targets domain.com, but it's here for clarity)
RewriteCond %{HTTP_HOST} ^subdomain\.domain\.com$ [NC]
RewriteRule .* - [L]

6 Blacklist via the referrer

Referrer-based blocking using .htaccess can be useful for blocking unwanted traffic originating from specific websites or traffic containing certain keywords in the referrer.

Here’s an example of how you can blacklist based on referrer in the .htaccess file:

RewriteEngine On
# Block traffic with referrers containing specific keywords
RewriteCond %{HTTP_REFERER} spammy-site\.com [NC,OR]
RewriteCond %{HTTP_REFERER} viagra [NC,OR]
RewriteCond %{HTTP_REFERER} weight\ loss [NC,OR]
RewriteCond %{HTTP_REFERER} hair\ growth [NC,OR]
RewriteCond %{HTTP_REFERER} Russian\ Brides [NC,OR]
RewriteCond %{HTTP_REFERER} Dropshipping [NC,OR]
RewriteCond %{HTTP_REFERER} Crypto [NC]
RewriteRule .* - [F]

7 Blacklist via cookies

Cookie-based methods are susceptible to several attacks, such as cookie tampering, cross-site scripting, and cross-site cookie manipulation. By embedding harmful characters, scripts, and other malicious content into cookies, adversaries can capitalize on these vulnerabilities. Fortunately, by leveraging Apache’s HTTP_COOKIE variable, we can filter out and block characters often linked to these cookie breaches. Below is an example that illustrates this approach:

7.1 Block any request that comes with a specific cookie value:

RewriteEngine On
# If the "badcookie" is set to "badvalue"
RewriteCond %{HTTP_COOKIE} ^.*badcookie=badvalue.*$ [NC]
RewriteRule .* - [F]

7.2 Blacklist based on the presence of a cookie regardless of its value:

RewriteEngine On
# If the "suspiciouscookie" exists, regardless of its value
RewriteCond %{HTTP_COOKIE} ^.*suspiciouscookie=.*$ [NC]
RewriteRule .* - [F]

8 Blacklist via the request

This code aims to block HTTP requests that contain newline or carriage return characters either in their raw or URL-encoded forms. Such characters might be part of a malicious attempt to perform HTTP Response Splitting attacks, XSS attacks, cache-poisoning, and similar dual-header exploits. Although these are some of the most common types of attacks, there are many others. I encourage you to check your server logs, do some research, and block them according to your needs.

<IfModule mod_rewrite.c> 
RewriteCond %{THE_REQUEST} (\\r|\\n|%0A|%0D) [NC] 
RewriteRule .* - [F,L] 

8.1 Blacklist via request-URI

Blacklisting based on the Request-URI serves several purposes in web server management and security. Here are some reasons why administrators might choose to blacklist certain Request-URIs:

1. Security:
a. Prevent access to sensitive directories or files that shouldn’t be exposed to the public.
b. Block known malicious paths that are frequently targeted by attackers, e.g., a common exploit path.
c. Counteract directory traversal attacks, where attackers attempt to access directories and files outside of the webroot.
2. Resource Management:
a. Block requests to resource-intensive scripts or endpoints to save server resources or to prevent DoS (Denial of Service) attacks.
b. Stop bots and scrapers from accessing large datasets or APIs frequently.
3. Content Management:
a. Restrict access to content that’s outdated or pending a future release.
b. Temporarily block access to parts of a site during maintenance or updates.
4. Regulatory and Compliance Reasons:
a. Block access to specific content that’s not meant to be accessed from certain regions, in line with data governance or local laws.
5. Usability:
a. Redirect old URLs to their new counterparts to provide a better user experience. (Though this is technically more about redirecting than blacklisting, the mechanism is similar.)
6. Reducing Noise:
a. Prevent automated tools, vulnerability scanners, or bots from hitting known paths (e.g., /wp-admin/ on a non-WordPress site) that generate unnecessary log entries.
7. SEO (Search Engine Optimization):
a. Direct search engines away from indexing duplicate, old, or non-public-facing content by blocking access.

<IfModule mod_rewrite.c>
    RewriteEngine On
    # Blacklist specific Request-URIs
    RewriteCond %{REQUEST_URI} ^/forbidden-folder/ [NC,OR]
    RewriteCond %{REQUEST_URI} ^/blocked-file\.php$ [NC,OR]
    RewriteCond %{REQUEST_URI} ^/unwanted-directory/.*$ [NC]
    RewriteRule .* - [F,L]