Huy Hòa
  • Home
  • Code Learn
    • WordPress
    • Woocommerce
    • Joomla
    • PHP
    • SEO – Marketing
  • Vietnam
  • Healthcare
    • Womens Health
  • Beauty
  • Lifehack
  • Free Tools
    • Dog Pregnancy Calculator
    • BMI Calculator
    • Upside Down Text
    • Vietnamese Calendar
    • Vietnamese Typing
  • Contact Us
Trending
  • Tet 2026: Everything You Need to Know About the Vietnamese Lunar New Year
  • PHP Foreach Loop Tutorial: Syntax, Examples, and Best Practices
  • Rash vs. Hives: How to Identify and Treat Them Naturally
  • How to Get Rid of a Pimple Inside Your Nose: A Comprehensive Guide
  • Ear Hygiene: How to Clean Your Ears the Right Way
Friday, May 30
Huy Hòa
  • Home
  • Code Learn
    • WordPress
    • Woocommerce
    • Joomla
    • PHP
    • SEO – Marketing
  • Vietnam
  • Healthcare
    • Womens Health
  • Beauty
  • Lifehack
  • Free Tools
    • Dog Pregnancy Calculator
    • BMI Calculator
    • Upside Down Text
    • Vietnamese Calendar
    • Vietnamese Typing
  • Contact Us
Huy Hòa
Home»WordPress»Optimize performance and security for WordPress using .htaccess

Optimize performance and security for WordPress using .htaccess

Facebook Twitter Pinterest LinkedIn Tumblr Email
htaccess
htaccess

htaccess is a special file that only works on Apache servers. WordPress also uses the .htaccess file to rewrite links when configuring Permalink. This article will provide you with code samples that can be used in .htaccess files for many different purposes for your WordPress website such as redirecting paths, security, blocking IPs, anti-comment spam…

Table of Contents

  • 1 What is a htaccess file?
  • 2 Where is .htaccess file?
  • 3 .htaccess file location
  • 4 Why You Can’t Find .htaccess File?
  • 5 Common uses for .htaccess files
      • 5.0.1 Redirecting a single URL
      • 5.0.2 Redirecting a single folder
      • 5.0.3 Redirecting old URLs to new URLs
      • 5.0.4 Redirecting www to Non-www using a 301 .htaccess redirect
      • 5.0.5 Redirecting Domain Names
  • 6 WordPress .htaccess
    • 6.1 How to locate and edit the .htaccess file in WordPress
      • 6.1.1 Editing .htaccess File from cPanel
      • 6.1.2 Edit htaccess WordPress File using FTP Client
      • 6.1.3 Editing .htaccess File with a Plugin
    • 6.2 Default WordPress htaccess
    • 6.3 Some advanced htaccess code for your WordPress site
    • 6.4 Other Example .htaccess Files
  • 7 Advanced Mod_Rewrites
    • 7.1 Directory Protection
    • 7.2 Password Protect wp-login.php
    • 7.3 Password Protect wp-admin
    • 7.4 Protect wp-content
    • 7.5 Protect wp-includes
    • 7.6 Common Exploits
    • 7.7 Stop Hotlinking
    • 7.8 Safe Request Methods
    • 7.9 Forbid Proxies
    • 7.10 Real wp-comments-post.php
    • 7.11 HTTP PROTOCOL
    • 7.12 SPECIFY CHARACTERS
    • 7.13 BAD Content-Length
    • 7.14 BAD Content-Type
    • 7.15 Missing HTTP_HOST
    • 7.16 Bogus Graphics Exploit
    • 7.17 No UserAgent, Not POST
    • 7.18 No Referer, No Comment
    • 7.19 Trackback Spam
    • 7.20 Map all URIs except those corresponding to existing files to a handler
    • 7.21 Map any request to a handler
    • 7.22 And for CGI scripts:
    • 7.23 Map URIs corresponding to existing files to a handler instead
    • 7.24 Deny access if var=val contains the string foo.
    • 7.25 Removing the Query String
    • 7.26 Adding to the Query String
    • 7.27 Rewriting For Certain Query Strings
    • 7.28 Modifying the Query String
    • 7.29 Forcing Non-WWW with HTTPS Site Addresses
    • 7.30 Forcing WWW with HTTPS Site Addresses with .htaccess
    • 7.31 Creating a Custom 404 Error Page with .htaccess
    • 7.32 Denying and Allowing Access
    • 7.33 Prevent Image Hotlinking
    • 7.34 Redirect a Single Page
    • 7.35 Alias a Single Directory
    • 7.36 Redirect an Entire Site
    • 7.37 Deny Access to Hidden Files and Directories
    • 7.38 Deny Access to Backup and Source Files
    • 7.39 Disable Directory Browsing
    • 7.40 Performance
    • 7.41 Set Expires Headers
    • 7.42 Set PHP Variables

What is a htaccess file?

htaccess files, also known as “distributed config files”, allow you to make configuration changes per directory. One or more configuration directives are placed in a specific document directory. The directives will apply to all subdirectories and that particular directory.

Apache uses .htaccess to handle configuration changes per directory.

The Apache Access Configuration file extension HTACCESS is a file with the HTACCESS extension. It stands for “hypertext access” These files are used to invoke an exception from the global settings which apply to all directories in an Apache website.

The global settings will be overridden if the file is placed in one directory. You can create HTACCESS files to redirect a URL, prevent directory listing, ban specific IP addresses, prevent hotlinking, etc.

This file can also be used to point to an htpasswd directory that stores credentials that prevent visitors from accessing the particular directory.

The .htaccess (hypertext access) file is a file located in the root directory of the hosting and managed and authorized by Apache. The .htaccess file can control and configure many things with a variety of parameters, it can change the default set values of Apache.

If exploited well, .htaccess will help you a lot with very little effort, just a few lines of command. The way you use the .htaccess file is also very simple, just open it with an editor, edit it, and save it as a .htaccess file.

Where is .htaccess file?

Your WordPress root directory contains the WordPress .htaccess file. The root directory could be labeled with a number of different names depending on the hosting provider. It can be found using File Manager within your hosting account’s control panel.
To create a .htaccess file in WordPress, you can use a text editor or a WordPress plugin.
Using a text editor

  1. Connect to your website using an FTP client, such as FileZilla.
  2. Navigate to the root directory of your WordPress installation.
  3. Create a new file called .htaccess.
  4. Open the .htaccess file in a text editor.
  5. Add the following code to the .htaccess file:
# BEGIN WordPress

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

This code is the default .htaccess file for WordPress. It tells Apache to enable the rewrite engine and to rewrite all requests to index.php.

  1. Save the .htaccess file.
  2. Upload the .htaccess file back to your website using your FTP client.

Using a WordPress plugin
There are a number of WordPress plugins that can help you create a .htaccess file. One popular plugin is Htaccess File Editor: https://wordpress.org/plugins/htaccess-file-editor/.

To use the Htaccess File Editor plugin, you will need to:

  1. Install and activate the plugin.
  2. Go to Settings > Htaccess File Editor.
  3. Click on the Create .htaccess button.
  4. The plugin will create a new .htaccess file with the default WordPress code.
  5. You can then make your own changes to the .htaccess file.
  6. Click on the Save Changes button.

Once you have saved your changes, the plugin will automatically update the .htaccess file on your website.

.htaccess file location

The .htaccess file is usually found in the root directory (usually public_html, www, htdocs …) and is on par with the robots.txt file. However, there are special cases where it is located outside the root directory of the website and affects all directories and websites located in that user.

You can find the .htaccess file in the following way:

  • For DirectAdmin host, you can go to File > select public_html > .htaccess
  • For the Cpanel host, select File Manager > select public_html > .htaccess

Note that some hosts will hide the .htaccess file. You must select “show hidden files” mode to see the .htaccess file

Why You Can’t Find .htaccess File?

There are 2 cases where you cannot find the .htaccess file.
Case 1: The .htaccess file has not been created.

Normally, WordPress will automatically create the htaccess file when you enable the Permalinks function. However, when you have not enabled this function, it will not create and you can create an htaccess file by going to WordPress Dashboard >> Settings >> Permalinks and then choosing one of 5 options:

  • Custom Structure,
  • Post name,
  • numeric, Month, and name,
  • Day and name

then click Save

Case 2: The .htaccess file has been hidden

Files that start with a dot are special files and are often hidden by the operating system or Files Explorer. .htaccess is often also hidden by popular FTP programs. Depending on the FTP program, you need to check the Force Showing Hidden Files box to show hidden files.

Common uses for .htaccess files

There are many uses for the .htaccess files. These are the most popular examples:

  • Redirections to certain URLs
  • Load custom error pages, like 404 pages
  • Forcing your website to use HTTPS over HTTP
  • Allow or deny access to specific IP addresses on your website
  • Password-protect specific directories on your server

These are just a few examples. This is the most requested section on this page. This section is frequently updated.

301 redirect htaccess

A 301 Permanent redirect permanently redirects one URL from another. To send visitors to a different URL, you can use .htaccess. This will tell search engines that a page moved to allow them to properly index the page.

A 301 redirect with the .htaccess is a common use:

  • You can redirect visitors to your new site by using a 301 redirect from the old domain after you move to a new domain.
  • You can use 301 redirects for users to go to new pages after moving pages from an old site to a new structure.
  • You can use 301 redirects after combining two websites to make sure visitors go to the new pages.

To create and manage redirects on HostPapa websites, you can use.htaccess file. You can either create a.htaccess files using File Manager in cPanel or upload a.htaccessfile you have created using a text editor on your own computer using FTP.

Note: The .htaccess files are hidden files so you will need to set up the cPanel File Manager and an FTP client to view hidden files on your computer. You can find out how to do this by following the steps below.

Developer tip To restore functionality to a site after adding or updating .htaccess files, rename or delete the file.

Redirecting a single URL

This code can be used to redirect a single URL. Make sure to substitute “old page”, for “new page”, in your page names. ):

301 RedirectMatch /oldpage/ /newpage/

Redirecting a single folder

The following steps can be used to redirect a folder to a different location:

 RewriteRule/?folder  [R,L]

For example, we used “folder” & “location”. Substitute folder and location names

Redirecting old URLs to new URLs

You can change the filenames of specific pages by entering the following code. Replace “oldpage”, “example” and “newpage” with your information:

redirect 301 /oldpage.html htto://www.example.com/abc/newpage.html

Redirecting www to Non-www using a 301 .htaccess redirect

You might want to create a redirect to avoid using a subdomain of www. If that is the case, then you will need to redirect to a version other than www. This is what you will need: Simply replace “example.” with your domain.

Redirecting Domain Names

Use the following code to redirect an entire domain to another domain:

RewriteEngine on RewriteCond ^(?:www. )oldsite\.com$ [NC]

RewriteRule ^https://newsite.com%REQUEST_URI [L,R=301]

WordPress .htaccess

This file is used by WordPress to control how Apache serves files from its root and subdirectories. WP modifies the file in order to allow for pretty permalinks.

This page can be used to repair a corrupted .htaccess file (e.g. A misbehaving plugin).

The .htaccess is either in the root directory of your webpage or in the directory you want to protect. If you are using Cpanel, htaccess file location is found in your website’s public_html folder (/home/username/public_html).
Because htaccess is a system configuration file and starts with a dot (.htaccess), so in some cases, you can’t see the file but you have to turn on showing hidden files to see it. That’s Why sometimes you Can’t Find the .htaccess file on your WordPress site.

For other FTP clients, you will find the option to show hidden files in-app settings or the preferences menu.

After enabling this option, you would be able to view all hidden files including the .htaccess file. In case you can’t find it, maybe it doesn’t exist. You can create it manually or by saving the setting in Permalink in WordPress Settings » Permalinks page.

There are several use cases for the .htaccess file. The most common examples include:

  • Add redirections for certain URLs or folders
  • Change default server error pages, like 500 pages, 501 pages, 404 pages,…
  • Force your site to use HTTPS instead of HTTP
  • Password-protect certain directories on your server
  • Prevent hotlinking

Using .htaccess files is a powerful tool for managing your server, but it can be tricky. Make sure you are familiar with making changes to your server before you start editing .htaccess files.

Please note that the default WordPress htaccess file only contains the following code, other code you found in your .htaccess file may be added by other plugins or server configurations.

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .*[E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$[L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

If you want to add other code to your .htaccess file, please ADD IT OUTSIDE of the above code snippet. Otherwise, it may lose when you update the WordPress setting.
For example:

Wrong:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .*[E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$[L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^huyhoa\.net
RewriteRule (.*) https://huyhoa.net/$1 [R=301,L]
# END WordPress

The Right Way to Add to .htaccess in WordPress CMS:

Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^mysite\.com
RewriteRule (.*) https://mysite.com/$1 [R=301,L]

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .*[E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$[L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

How to locate and edit the .htaccess file in WordPress

The .htaccess file is usually hidden. WordPress hides the .htaccess file because it is very important and can be accidentally deleted.

To locate the .htaccess file, log in to your WordPress hosting account. Next, navigate to the Cpanel. Launch the File Manager, then choose the Public_html folder.

You will need to make the .htaccess file visible. To do this, select Setting. This is usually located in the right-hand corner of the cPanel Folder Manager. A window will appear once you have selected Settings. Select the option Show hidden files.

Go back to the public_html folder. The .htaccess should now be visible.

Editing the .htaccess file can be done in many ways. We will show you all in the following paragraphs.

  1. Edit htaccess WordPress File from cPanel
  2. Edit htaccess WordPress File using FTP Client
  3. Or Edit htaccess WordPress File with a Plugin

Backups

Take a complete backup before you make any changes to WordPress .htaccess files. It is important to keep the file safe and avoid accidentally deleting it. You may not see the desired modification on your site if you make changes to the .htaccess file.

It could even cause the site to be unusable. No matter what happens, you can restore your site quickly to its original state if you have a backup. It’s easy.
Let’s now show you how to edit your .htaccess file.

Editing .htaccess File from cPanel

First:

Log in to your hosting account. Next, navigate to Cpanel and choose File Manager.

2nd Step:

Go to the Public_html folder in the File Manager. This folder contains the .htaccess file. Right-click to locate it and choose Edit.

Right-click to select Edit

That’s it. You can now insert code snippets to modify your website.

Edit htaccess WordPress File using FTP Client

FTP clients are another way to edit the .htaccess files. FTP clients are a tool that connects your website and your computer. Filezilla is an FTP client that allows you to access your website’s files from any computer on your network. This is how an FTP client can edit the file .htaccess.

Step 1: First, install Filezilla
Download Filezilla and install it on your computer. This is the most popular FTP client. Open it once you have it installed.

Step 2 – Find Your FTP Credentials
You will need your FTP credentials to connect Filezilla to your website. It’s possible to ask your hosting provider, but you can also search for it yourself.

FTP credentials are made up of hostname and username, password, and port number.

Filezilla offers several options in the top window that allow you to insert your FTP credentials. After you’ve done this, click Quickconnect to connect the software to your website.
Insert your hostname, username, and password, as well as the port number.

Step 3: Locate and Edit the .htaccess file

Filezilla can be divided into two parts. The local section shows you a collection of files from your computer. The remote shows you a collection of files from your website.

Select public_html from the remote section. The Filename section, located below the Remote site section, will contain the contents of the folder.

Right-click on the .htaccess file and choose Edit.

Go to Remote site > Filename>.htaccess
Next, we will show you how to modify your .htaccess file with a plugin.

Editing .htaccess File with a Plugin

Editing the .htaccess files via cPanel or via FTP client can be a little risky as you need to access the site’s backup and then edit the file. It can be overwhelming for website owners to access WordPress files. It wouldn’t surprise you to find yourself in this situation. A plugin is a safer option.

Although there are many plugins available to edit .htaccess files, we decided on Htaccess Editor after careful consideration. This plugin has more than 50,000 active installations and has received over 20 5-star ratings. It’s also frequently updated, according to the repository page. Htaccess Editor meets all requirements for selecting the correct plugin.

To ensure compatibility, you should first stage your website before installing the plugin. Compatibility issues could cause problems such as misbehaving sites and the inability to use certain plugins.

After you have tested it, you can edit the .htaccess file using a plugin.

First:

Install and activate HTML Access Editor on your WordPress website.

2nd Step:

Next, navigate to Settings and then choose WP HTMLaccess Editor. This will take you directly to the .htaccess file. You can insert any code snippet, but you must save the changes.

To edit the .htaccess file in WordPress, you can use a text editor or a WordPress plugin.
Using a text editor

  1. Connect to your website using an FTP client, such as FileZilla.
  2. Navigate to the root directory of your WordPress installation.
  3. Locate the .htaccess file.
  4. Open the .htaccess file in a text editor.
  5. Make your changes to the .htaccess file.
  6. Save the .htaccess file.
  7. Upload the .htaccess file back to your website using your FTP client.

Using a WordPress plugin
There are a number of WordPress plugins that can help you edit the .htaccess file. One popular plugin is Htaccess File Editor
To use the Htaccess File Editor plugin, you will need to:

  1. Install and activate the plugin.
  2. Go to Settings > Htaccess File Editor.
  3. Click on the Edit .htaccess button.
  4. Make your changes to the .htaccess file.
  5. Click on the Save Changes button.

Once you have saved your changes, the plugin will automatically update the .htaccess file on your website.

Default WordPress htaccess

WordPress should create a.htaccess for you automatically – but sometimes it’s not able to due to file permissions issues. Follow the below steps if that happens.

Log in to your WordPress dashboard, and then go to \

Scroll to the bottom, and then click Save Changes.

WordPress will now attempt to create a.htaccess. file. WordPress will now attempt to generate a .htaccess file. If it fails, you’ll get an error message at the bottom saying “.htaccess files are not writeable”.

The .htaccess file must be manually created. Log in to the control panel of your hosting account.

Start the File Manager.

Click on the public_html folder in the navigation menu located on the lefthand-hand side of the screen.

Click the +File button in the toolbar near the top of the screen.

In the New File Name input box, type “.htaccess”.

Click on Create New File.

To edit the file, right-click it.

You can add one of these codes.

You can use Basic WordPress if you only have WordPress on 1 domain.
The default WordPress .htaccess file can be found in the root directory of your WordPress installation. If you don’t have a .htaccess file, you can create one using a text editor.
Here is the content of the default WordPress .htaccess file:

# BEGIN WordPress

RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

# END WordPress

This .htaccess file includes the following rules:

  • The RewriteEngine On directive tells Apache to enable the rewrite engine.
  • The RewriteBase / directive tells Apache that the root directory of the website is /.
  • The RewriteRule ^index\.php$ - [L] directive tells Apache to rewrite any request for index.php itself. This is useful for preventing people from accessing the WordPress core files directly.
  • The RewriteCond %{REQUEST_FILENAME} !-f directive tells Apache to only rewrite requests for files that do not exist.
  • The RewriteCond %{REQUEST_FILENAME} !-d directive tells Apache to only rewrite requests for directories that do not exist.
  • The RewriteRule . /index.php [L] directive tells Apache to rewrite all other requests to index.php. This is how WordPress handles permalinks.

The default WordPress .htaccess file also includes some security settings, such as the following:

  • The Order deny,allow directive tells Apache to deny access to all files by default, and then allow access to specific files.
  • The Allow from all directive tells Apache to allow access to all files from all IP addresses.

Multisite

WordPress 3.5 and up
If you activated Multisite on WordPress 3.5 or later, use one of these.

Subfolder Example

# BEGIN WordPress Multisite
# Using subfolder network type: https://wordpress.org/support/article/htaccess/#multisite

RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]

# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]

# END WordPress Multisite

SubDomain Example

# BEGIN WordPress Multisite
# Using subdomain network type: https://wordpress.org/support/article/htaccess/#multisite

RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]

# add a trailing slash to /wp-admin
RewriteRule ^wp-admin$ wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^(wp-(content|admin|includes).*) $1 [L]
RewriteRule ^(.*\.php)$ $1 [L]
RewriteRule . index.php [L]

# END WordPress Multisite

Save and close the file.
Now that you know how to create a default .htaccess file for your WordPress site if it doesn’t exist already, you’re ready to edit it. Let’s look at how below.

Some advanced htaccess code for your WordPress site

Here are some specific examples, this is the most popular section of this page. Updated frequently.

Redirect Everyone Except the IP address to an alternate page

ErrorDocument 403 https://www.yahoo.com/
Order deny,allow
Deny from all
Allow from 123.123.123.123

When developing sites

This lets Google crawl the page, lets me access it without a password, and lets my client access the page WITH a password. It also allows for XHTML and CSS validation! (w3.org)

AuthName "Under Development"
AuthUserFile /web/sitename.com/.htpasswd
AuthType basic
Require valid-user
Order deny,allow
Deny from all
Allow from 208.113.134.190 w3.org htmlhelp.com googlebot.com
Satisfy Any

Fix double-login prompt
Redirect non-HTTPS requests to the HTTPS server and ensure that .htpasswd authorization can only be entered across HTTPS

SSLOptions +StrictRequire
SSLRequireSSL
SSLRequire %{HTTP_HOST} eq "huyhoa.net"
ErrorDocument 403 https://huyhoa.net

Set the Timezone of the Server (GMT)

SetEnv TZ America/Indianapolis

Administrator Email for ErrorDocument

SetEnv SERVER_ADMIN [email protected]

ServerSignature for ErrorDocument

ServerSignature off | on | email

Charset and Language headers

AddDefaultCharset UTF-8
DefaultLanguage en-US

Disallow Script Execution

Options -ExecCGI
AddHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi

Deny Request Methods

RewriteCond %{REQUEST_METHOD} !^(GET|HEAD|OPTIONS|POST|PUT)
RewriteRule .? - [F]

Force “File Save As” Prompt

AddType application/octet-stream .avi .mpg .mov .pdf .xls .mp4

Show CGI Source Code

RemoveHandler cgi-script .pl .py .cgi
AddType text/plain .pl .py .cgi

Serve all .pdf files on your site using .htaccess and mod_rewrite with the PHP script.

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.+)\.pdf$  /cgi-bin/pdf.php?file=$1 [L,NC,QSA]

Rewrite to www

RewriteCond %{REQUEST_URI} !^/(robots\.txt|favicon\.ico|sitemap\.xml)$
RewriteCond %{HTTP_HOST} !^www\.yourdomain\.com$ [NC]
RewriteRule ^(.*)$ https://www.yourdomain.com/$1 [R=301,L]

Rewrite to www dynamically

RewriteCond %{REQUEST_URI} !^/robots\.txt$ [NC]
RewriteCond %{HTTP_HOST} !^www\.[a-z-]+\.[a-z]{2,6} [NC]
RewriteCond %{HTTP_HOST} ([a-z-]+\.[a-z]{2,6})$   [NC]
RewriteRule ^/(.*)$ https://%1/$1 [R=301,L]

301 Redirect Old File

Redirect 301 /old/file.html https://www.yournewdomain.com/new/file/

301 Redirect Entire Directory

RedirectMatch 301 /blog(.*) https://www.google.com/$1

Protecting your PHP.cgi

<FilesMatch "^php5?\.(ini|cgi)$">
Order Deny,Allow
Deny from All
Allow from env=REDIRECT_STATUS
</FilesMatch>

Set-Cookie based on Request
This code sends the Set-Cookie header to create a cookie on the client with the value of a matching item in 2nd parentheses.

RewriteRule ^(.*)(de|es|fr|it|ja|ru|en)/$ - [co=lang:$2:.yourdomain.com:7200:/]

Set-Cookie with env variable

Header set Set-Cookie "language=%{lang}e; path=/;" env=lang

Custom ErrorDocuments

ErrorDocument 100 /100_CONTINUE
ErrorDocument 101 /101_SWITCHING_PROTOCOLS
ErrorDocument 102 /102_PROCESSING
ErrorDocument 200 /200_OK
ErrorDocument 201 /201_CREATED
ErrorDocument 202 /202_ACCEPTED
ErrorDocument 203 /203_NON_AUTHORITATIVE
ErrorDocument 204 /204_NO_CONTENT
ErrorDocument 205 /205_RESET_CONTENT
ErrorDocument 206 /206_PARTIAL_CONTENT
ErrorDocument 207 /207_MULTI_STATUS
ErrorDocument 300 /300_MULTIPLE_CHOICES
ErrorDocument 301 /301_MOVED_PERMANENTLY
ErrorDocument 302 /302_MOVED_TEMPORARILY
ErrorDocument 303 /303_SEE_OTHER
ErrorDocument 304 /304_NOT_MODIFIED
ErrorDocument 305 /305_USE_PROXY
ErrorDocument 307 /307_TEMPORARY_REDIRECT
ErrorDocument 400 /400_BAD_REQUEST
ErrorDocument 401 /401_UNAUTHORIZED
ErrorDocument 402 /402_PAYMENT_REQUIRED
ErrorDocument 403 /403_FORBIDDEN
ErrorDocument 404 /404_NOT_FOUND
ErrorDocument 405 /405_METHOD_NOT_ALLOWED
ErrorDocument 406 /406_NOT_ACCEPTABLE
ErrorDocument 407 /407_PROXY_AUTHENTICATION_REQUIRED
ErrorDocument 408 /408_REQUEST_TIME_OUT
ErrorDocument 409 /409_CONFLICT
ErrorDocument 410 /410_GONE
ErrorDocument 411 /411_LENGTH_REQUIRED
ErrorDocument 412 /412_PRECONDITION_FAILED
ErrorDocument 413 /413_REQUEST_ENTITY_TOO_LARGE
ErrorDocument 414 /414_REQUEST_URI_TOO_LARGE
ErrorDocument 415 /415_UNSUPPORTED_MEDIA_TYPE
ErrorDocument 416 /416_RANGE_NOT_SATISFIABLE
ErrorDocument 417 /417_EXPECTATION_FAILED
ErrorDocument 422 /422_UNPROCESSABLE_ENTITY
ErrorDocument 423 /423_LOCKED
ErrorDocument 424 /424_FAILED_DEPENDENCY
ErrorDocument 426 /426_UPGRADE_REQUIRED
ErrorDocument 500 /500_INTERNAL_SERVER_ERROR
ErrorDocument 501 /501_NOT_IMPLEMENTED
ErrorDocument 502 /502_BAD_GATEWAY
ErrorDocument 503 /503_SERVICE_UNAVAILABLE
ErrorDocument 504 /504_GATEWAY_TIME_OUT
ErrorDocument 505 /505_VERSION_NOT_SUPPORTED
ErrorDocument 506 /506_VARIANT_ALSO_VARIES
ErrorDocument 507 /507_INSUFFICIENT_STORAGE
ErrorDocument 510 /510_NOT_EXTENDED

Implementing a Caching Scheme with .htaccess

# year
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf|mp3|mp4)$">
Header set Cache-Control "public"
Header set Expires "Thu, 15 Apr 2010 20:00:00 GMT"
Header unset Last-Modified
</FilesMatch>
#2 hours
<FilesMatch "\.(html|htm|xml|txt|xsl)$">
Header set Cache-Control "max-age=7200, must-revalidate"
</FilesMatch>
<FilesMatch "\.(js|css)$">
SetOutputFilter DEFLATE
Header set Expires "Thu, 15 Apr 2010 20:00:00 GMT"
</FilesMatch>

Password Protect a single file

<Files login.php>
AuthName "Prompt"
AuthType Basic
AuthUserFile /web/google.com/.htpasswd
Require valid-user
</Files>

Password Protect multiple files

<FilesMatch "^(private|phpinfo).*$">
AuthName "Development"
AuthUserFile /.htpasswd
AuthType basic
Require valid-user
</FilesMatch>

Send Custom Headers

Header set P3P "policyref="https://www.google.com/w3c/p3p.xml""
Header set X-Pingback "https://www.google.com/xmlrpc.php"
Header set Content-Language "en-US"
Header set Vary "Accept-Encoding"

Blocking based on User-Agent Header

SetEnvIfNoCase ^User-Agent$ .*(craftbot|download|extract|stripper|sucker|ninja|clshttp|webspider|leacher|collector|grabber|webpictures) HTTP_SAFE_BADBOT
SetEnvIfNoCase ^User-Agent$ .*(libwww-perl|aesop_com_spiderman) HTTP_SAFE_BADBOT
Deny from env=HTTP_SAFE_BADBOT

Blocking with RewriteCond

RewriteCond %{HTTP_USER_AGENT} ^.*(craftbot|download|extract|stripper|sucker|ninja|clshttp|webspider|leacher|collector|grabber|webpictures).*$ [NC]
RewriteRule . - [F,L]

.htaccess for mod_php

SetEnv PHPRC /location/todir/containing/phpinifile

.htaccess for PHP as CGI

AddHandler php-cgi .php .htm
Action php-cgi /cgi-bin/php5.cgi

Shell wrapper for custom php.ini

#!/bin/sh
export PHP_FCGI_CHILDREN=3
exec php5.cgi -c /abs/php5/php.ini

Add values from HTTP Headers

SetEnvIfNoCase ^If-Modified-Since$ "(.+)" HTTP_IF_MODIFIED_SINCE=$1
SetEnvIfNoCase ^If-None-Match$ "(.+)" HTTP_IF_NONE_MATCH=$1
SetEnvIfNoCase ^Cache-Control$ "(.+)" HTTP_CACHE_CONTROL=$1
SetEnvIfNoCase ^Connection$ "(.+)" HTTP_CONNECTION=$1
SetEnvIfNoCase ^Keep-Alive$ "(.+)" HTTP_KEEP_ALIVE=$1
SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
SetEnvIfNoCase ^Cookie$ "(.+)" HTTP_MY_COOKIE=$1

Stop hotlinking

RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https://(www\.)?askapache\.com/.*$ [NC]
RewriteRule \.(gif|jpg|swf|flv|png)$ https://www.google.com/feed.gif [R=302,L]

Other Example .htaccess Files

# Set the Time Zone of your Server
SetEnv TZ America/Indianapolis
# ServerAdmin:  This address appears on some server-generated pages, such as error documents.
SetEnv SERVER_ADMIN [email protected]
# Possible values for the Options directive are "None", "All", or any combination of:
#  Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
Options -ExecCGI -MultiViews -Includes -Indexes FollowSymLinks
# DirectoryIndex: sets the file that Apache will serve if a directory is requested.
DirectoryIndex index.html index.php /index.php
# Action lets you define media types that will execute a script whenever
# a matching file is called. This eliminates the need for repeated URL
# pathnames for oft-used CGI file processors.
# Format: Action media/type /cgi-script/location
# Format: Action handler-name /cgi-script/location
#
Action php5-cgi /bin/php.cgi
# AddHandler allows you to map certain file extensions to "handlers":
# actions unrelated to filetype. These can be either built into the server
# or added with the Action directive (see below)
#
# To use CGI scripts outside of ScriptAliased directories:
# (You will also need to add "ExecCGI" to the "Options" directive.)
#
AddHandler php-cgi .php .inc
# Commonly used filename extensions to character sets.
AddDefaultCharset UTF-8
# AddType allows you to add to or override the MIME configuration
AddType 'application/rdf+xml; charset=UTF-8' .rdf
AddType 'application/xhtml+xml; charset=UTF-8' .xhtml
AddType 'application/xhtml+xml; charset=UTF-8' .xhtml.gz
AddType 'text/html; charset=UTF-8' .html
AddType 'text/html; charset=UTF-8' .html.gz
AddType application/octet-stream .rar .chm .bz2 .tgz .msi .pdf .exe
AddType application/vnd.ms-excel .csv
AddType application/x-httpd-php-source .phps
AddType application/x-pilot .prc .pdb
AddType application/x-shockwave-flash .swf
AddType application/xrds+xml .xrdf
AddType text/plain .ini .sh .bsh .bash .awk .nawk .gawk .csh .var .c .in .h .asc .md5 .sha .sha1
AddType video/x-flv .flv
# AddEncoding allows you to have certain browsers uncompress information on the fly. Note: Not all browsers support this.
AddEncoding x-compress .Z
AddEncoding x-gzip .gz .tgz
# DefaultType: the default MIME type the server will use for a document.
DefaultType text/html
# Optionally add a line containing the server version and virtual host
# name to server-generated pages (internal error documents, FTP directory
# listings, mod_status and mod_info output etc., but not CGI generated
# documents or custom error documents).
# Set to "EMail" to also include a mailto: link to the ServerAdmin.
# Set to one of:  On | Off | EMail
ServerSignature Off
## MAIN DEFAULTS
Options +ExecCGI -Indexes
DirectoryIndex index.html index.htm index.php
DefaultLanguage en-US
AddDefaultCharset UTF-8
ServerSignature Off

## ENVIRONMENT VARIABLES
SetEnv PHPRC /webroot/includes
SetEnv TZ America/Indianapolis

SetEnv SERVER_ADMIN [email protected]

## MIME TYPES
AddType video/x-flv .flv
AddType application/x-shockwave-flash .swf
AddType image/x-icon .ico

## FORCE FILE TO DOWNLOAD INSTEAD OF APPEAR IN BROWSER

AddType application/octet-stream .mov .mp3 .zip

## ERRORDOCUMENTS

ErrorDocument 400 /e400/
ErrorDocument 401 /e401/
ErrorDocument 402 /e402/
ErrorDocument 403 /e403/
ErrorDocument 404 /e404/

# Handlers be builtin, included in a module, or added with Action directive
# default-handler: default, handles static content (core)
#   send-as-is: Send file with HTTP headers (mod_asis)
#   cgi-script: treat file as CGI script (mod_cgi)
#    imap-file: Parse as an imagemap rule file (mod_imap)
#   server-info: Get server config info (mod_info)
#  server-status: Get server status report (mod_status)
#    type-map: type map file for content negotiation (mod_negotiation)
#  fastcgi-script: treat file as fastcgi script (mod_fastcgi)
#


## PARSE AS CGI
AddHandler cgi-script .cgi .pl .spl

## RUN PHP AS APACHE MODULE
AddHandler application/x-httpd-php .php .htm

## RUN PHP AS CGI
AddHandler php-cgi .php .htm

## CGI PHP WRAPPER FOR CUSTOM PHP.INI
AddHandler phpini-cgi .php .htm
Action phpini-cgi /cgi-bin/php5-custom-ini.cgi

## FAST-CGI SETUP WITH PHP-CGI WRAPPER FOR CUSTOM PHP.INI
AddHandler fastcgi-script .fcgi
AddHandler php-cgi .php .htm
Action php-cgi /cgi-bin/php5-wrapper.fcgi

## CUSTOM PHP CGI BINARY SETUP
AddHandler php-cgi .php .htm
Action php-cgi /cgi-bin/php.cgi

## PROCESS SPECIFIC FILETYPES WITH CGI-SCRIPT
Action image/gif /cgi-bin/img-create.cgi

## CREATE CUSTOM HANDLER FOR SPECIFIC FILE EXTENSIONS
AddHandler custom-processor .ssp
Action custom-processor /cgi-bin/myprocessor.cgi

### HEADER CACHING
<FilesMatch "\.(flv|gif|jpg|jpeg|png|ico)$">
Header set Cache-Control "max-age=2592000"
</FilesMatch>
<FilesMatch "\.(js|css|pdf|swf)$">
Header set Cache-Control "max-age=604800"
</FilesMatch>
<FilesMatch "\.(html|htm|txt)$">
Header set Cache-Control "max-age=600"
</FilesMatch>
<FilesMatch "\.(pl|php|cgi|spl|scgi|fcgi)$">
Header unset Cache-Control
</FilesMatch>

## ALTERNATE EXPIRES CACHING
ExpiresActive On
ExpiresDefault A604800
ExpiresByType image/x-icon A2592000
ExpiresByType application/x-javascript A2592000
ExpiresByType text/css A2592000
ExpiresByType text/html A300

<FilesMatch "\.(pl|php|cgi|spl|scgi|fcgi)$">
ExpiresActive Off
</FilesMatch>

## META HTTP-EQUIV REPLACEMENTS
<FilesMatch "\.(html|htm|php)$">
Header set imagetoolbar "no"
</FilesMatch>

Here are some default MOD_REWRITE code examples.

## REWRITE DEFAULTS
RewriteEngine On
RewriteBase /

## REQUIRE SUBDOMAIN
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^subdomain\.askapache\.com$ [NC]
RewriteRule ^/(.*)$ https://subdomain.google.com/$1 [L,R=301]

## SEO REWRITES
RewriteRule ^(.*)/ve/(.*)$ $1/voluntary-employee/$2 [L,R=301]
RewriteRule ^(.*)/hsa/(.*)$ $1/health-saving-account/$2 [L,R=301]

## WORDPRESS
RewriteCond %{REQUEST_FILENAME} !-f  # Existing File
RewriteCond %{REQUEST_FILENAME} !-d  # Existing Directory
RewriteRule . /index.php [L]

## ALTERNATIVE ANTI-HOTLINKING
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https://(subdomain\.)?askapache\.com/.*$ [NC]
RewriteRule ^.*\.(bmp|tif|gif|jpg|jpeg|jpe|png)$ - [F]

## REDIRECT HOTLINKERS
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https://(subdomain\.)?askapache\.com/.*$ [NC]
RewriteRule ^.*\.(bmp|tif|gif|jpg|jpeg|jpe|png)$ https://google.com [R]

## DENY REQUEST BASED ON REQUEST METHOD
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK|OPTIONS|HEAD)$ [NC]
RewriteRule ^.*$ - [F]

## REDIRECT UPLOADS
RewriteCond %{REQUEST_METHOD} ^(PUT|POST)$ [NC]
RewriteRule ^(.*)$ /cgi-bin/form-upload-processor.cgi?p=$1 [L,QSA]

## REQUIRE SSL EVEN WHEN MOD_SSL IS NOT LOADED
RewriteCond %{HTTPS} !=on [NC]
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]

### ALTERNATATIVE TO USING ERRORDOCUMENT
# https://www.htaccesselite.com/d/htaccess-errordocument-examples-vt11.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /error.php [L]

## SEO REDIRECTS
Redirect 301 /2006/oldfile.html https://subdomain.google.com/newfile.html
RedirectMatch 301 /o/(.*)$ https://subdomain.google.com/s/dl/$1

Examples of protecting your files and securing them with password protection.

#
# Require (user|group|valid-user) (username|groupname)
#
## BASIC PASSWORD PROTECTION
AuthType basic
AuthName "prompt"
AuthUserFile /.htpasswd
AuthGroupFile /dev/null
Require valid-user

## ALLOW FROM IP OR VALID PASSWORD
Require valid-user
Allow from 192.168.1.23
Satisfy Any

## PROTECT FILES
<FilesMatch "\.(htaccess|htpasswd|ini|phps|fla|psd|log|sh)$">
Order Allow,Deny
Deny from all
</FilesMatch>

## PREVENT HOTLINKING
SetEnvIfNoCase Referer "^https://subdomain.google.com/" good
SetEnvIfNoCase Referer "^$" good
<FilesMatch "\.(png|jpg|jpeg|gif|bmp|swf|flv)$">
Order Deny,Allow
Deny from all
Allow from env=good
ErrorDocument 403 https://www.google.com/intl/en_ALL/images/logo.gif
ErrorDocument 403 /images/you_bad_hotlinker.gif
</FilesMatch>

## LIMIT UPLOAD FILE SIZE TO PROTECT AGAINST DOS ATTACK
#bytes, 0-2147483647(2GB)
LimitRequestBody 10240000

## MOST SECURE WAY TO REQUIRE SSL
SSLOptions +StrictRequire
SSLRequireSSL
SSLRequire %{HTTP_HOST} eq "google.com"
ErrorDocument 403 https://google.com

## COMBINED DEVELOPER HTACCESS CODE-USE THIS
<FilesMatch "\.(flv|gif|jpg|jpeg|png|ico|js|css|pdf|swf|html|htm|txt)$">
Header set Cache-Control "max-age=5"
</FilesMatch>
AuthType basic
AuthName "Ooops! Temporarily Under Construction..."
AuthUserFile /.htpasswd
AuthGroupFile /dev/null
Require valid-user      # password prompt for everyone else
Order Deny,Allow
Deny from all
Allow from 192.168.64.5   # Your, the developers IP address
Allow from w3.org      # css/xhtml check 
Allow from googlebot.com   # Allows google to crawl your pages
Satisfy Any        # no password required if host/ip is Allowed

## DONT HAVE TO EMPTY CACHE OR RELOAD TO SEE CHANGES
ExpiresDefault A5 #If using mod_expires
<FilesMatch "\.(flv|gif|jpg|jpeg|png|ico|js|css|pdf|swf|html|htm|txt)$">
Header set Cache-Control "max-age=5"
</FilesMatch>

## ALLOW ACCESS WITH PASSWORD OR NO PASSWORD FOR SPECIFIC IP/HOSTS
AuthType basic
AuthName "Ooops! Temporarily Under Construction..."
AuthUserFile /.htpasswd
AuthGroupFile /dev/null
Require valid-user      # password prompt for everyone else
Order Deny,Allow
Deny from all
Allow from 192.168.64.5   # Your, the developers IP address
Allow from w3.org      # css/xhtml 
Allow from googlebot.com   # Allows google to crawl your pages
Satisfy Any        # no password required if host/ip is Allowed

Advanced Mod_Rewrites

Here are some specific htaccess examples taken mostly from my WordPress Password Protection plugin, which does a lot more than password protection as you will see from the following mod_rewrite examples.

These are a few of the mod_rewrite uses that BlogSecurity declared pushed the boundaries of Mod_Rewrite! Some of these snippets are quite exotic and unlike anything, you may have seen before, also only for those who understand them as they can kill a website pretty quickly.

Directory Protection

Enable the DirectoryIndex Protection, preventing directory index listings and defaulting.

Options -Indexes
DirectoryIndex index.html index.php /index.php

Password Protect wp-login.php

Requires a valid user/pass to access the login page

<Files wp-login.php>
Order Deny,Allow
Deny from All
Satisfy Any
AuthName "Protected By AskApache"
AuthUserFile /web/google.com/.htpasswda1
AuthType Basic
Require valid-user
</Files>

Password Protect wp-admin

Requires a valid user/pass to access any non-static (CSS, js, images) file in this directory.

Options -ExecCGI -Indexes +FollowSymLinks -Includes
DirectoryIndex index.php /index.php
Order Deny,Allow
Deny from All
Satisfy Any
AuthName "Protected By AskApache"
AuthUserFile /web/google.com/.htpasswda1
AuthType Basic
Require valid-user
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|mp3|mpg|mp4|mov|wav|wmv|png|gif|swf|css|js)$">
Allow from All
</FilesMatch>
<FilesMatch "(async-upload)\.php$">
<IfModule mod_security.c>
SecFilterEngine Off
</IfModule>
Allow from All
</FilesMatch>

Protect wp-content

Denies any Direct request for files ending in .php with a 403 Forbidden. May break plugins/themes

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /wp-content/.*$ [NC]
RewriteCond %{REQUEST_FILENAME} !^.+flexible-upload-wp25js.php$
RewriteCond %{REQUEST_FILENAME} ^.+\.(php|html|htm|txt)$
RewriteRule .? - [F,NS,L]

Protect wp-includes

Denies any Direct request for files ending in .php with a 403 Forbidden.. May break plugins/themes

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /wp-includes/.*$ [NC]
RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ /wp-includes/js/.+/.+\ HTTP/ [NC]
RewriteCond %{REQUEST_FILENAME} ^.+\.php$
RewriteRule .? - [F,NS,L]

Common Exploits

Block common exploit requests with 403 Forbidden. These can help a lot, and may break some plugins.

RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ ///.*\ HTTP/ [NC,OR]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\?\=?(http|ftp|ssl|https):/.*\ HTTP/ [NC,OR]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\?\?.*\ HTTP/ [NC,OR]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.(asp|ini|dll).*\ HTTP/ [NC,OR]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.(htpasswd|htaccess|aahtpasswd).*\ HTTP/ [NC]
RewriteRule .? - [F,NS,L]

Stop Hotlinking

Denies any request for static files (images, CSS, etc) if the referrer is not a local site or is empty.

RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]
RewriteCond %{HTTP_REFERER} !^https://www.google.com.*$ [NC]
RewriteRule \.(ico|pdf|flv|jpg|jpeg|mp3|mpg|mp4|mov|wav|wmv|png|gif|swf|css|js)$ - [F,NS,L]

Safe Request Methods

Denies any request not using GET, PROPFIND, POST, OPTIONS, PUT, HEAD

RewriteCond %{REQUEST_METHOD} !^(GET|HEAD|POST|PROPFIND|OPTIONS|PUT)$ [NC]
RewriteRule .? - [F,NS,L]

Forbid Proxies

Denies any POST Request using a Proxy Server. Can still access the site, but not comment.

RewriteCond %{REQUEST_METHOD} =POST
RewriteCond %{HTTP:VIA}%{HTTP:FORWARDED}%{HTTP:USERAGENT_VIA}%{HTTP:X_FORWARDED_FOR}%{HTTP:PROXY_CONNECTION} !^$ [OR]
RewriteCond %{HTTP:XPROXY_CONNECTION}%{HTTP:HTTP_PC_REMOTE_ADDR}%{HTTP:HTTP_CLIENT_IP} !^$
RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]
RewriteRule .? - [F,NS,L]

Real wp-comments-post.php

Denies any POST attempt made to a non-existing wp-comments-post.php

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*/wp-comments-post\.php.*\ HTTP/ [NC]
RewriteRule .? - [F,NS,L]

HTTP PROTOCOL

Denies any badly formed HTTP PROTOCOL in the request, 0.9, 1.0, and 1.1 only

RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ .+\ HTTP/(0\.9|1\.0|1\.1) [NC]
RewriteRule .? - [F,NS,L]

SPECIFY CHARACTERS

Denies any request for a URL containing characters other than “a-zA-Z0-9.+/-?=&” – REALLY helps but may break your site depending on your links.

RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]
RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ [a-zA-Z0-9\.\+_/\-\?\=\&]+\ HTTP/ [NC]
RewriteRule .? - [F,NS,L]

BAD Content-Length

Denies any POST request that doesn’t have a Content-Length Header

RewriteCond %{REQUEST_METHOD} =POST
RewriteCond %{HTTP:Content-Length} ^$
RewriteCond %{REQUEST_URI} !^/(wp-admin/|wp-content/plugins/|wp-includes/).* [NC]
RewriteRule .? - [F,NS,L]

BAD Content-Type

Denies any POST request with a content type other than application/x-www-form-urlencoded|multipart/form-data

RewriteCond %{REQUEST_METHOD} =POST
RewriteCond %{HTTP:Content-Type} !^(application/x-www-form-urlencoded|multipart/form-data.*(boundary.*)?)$ [NC]
RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]
RewriteRule .? - [F,NS,L]

Missing HTTP_HOST

Denies requests that don’t contain an HTTP Host Header.

RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]
RewriteCond %{HTTP_HOST} ^$
RewriteRule .? - [F,NS,L]

Bogus Graphics Exploit

Denies obvious exploit using bogus graphics

RewriteCond %{HTTP:Content-Disposition} \.php [NC]
RewriteCond %{HTTP:Content-Type} image/.+ [NC]
RewriteRule .? - [F,NS,L]

No UserAgent, Not POST

Denies POST requests by blank user-agents. May prevent a small number of visitors from POSTING.

RewriteCond %{REQUEST_METHOD} =POST
RewriteCond %{HTTP_USER_AGENT} ^-?$
RewriteCond %{REQUEST_URI} !^/(wp-login.php|wp-admin/|wp-content/plugins/|wp-includes/).* [NC]
RewriteRule .? - [F,NS,L]

No Referer, No Comment

Denies any comment attempt with a blank HTTP_REFERER field, highly indicative of spam. May prevent some visitors from POSTING.

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*/wp-comments-post\.php.*\ HTTP/ [NC]
RewriteCond %{HTTP_REFERER} ^-?$
RewriteRule .? - [F,NS,L]

Trackback Spam

Denies obvious trackback spam.

RewriteCond %{REQUEST_METHOD} =POST
RewriteCond %{HTTP_USER_AGENT} ^.*(opera|mozilla|firefox|msie|safari).*$ [NC]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.+/trackback/?\ HTTP/ [NC]
RewriteRule .? - [F,NS,L]

Map all URIs except those corresponding to existing files to a handler

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule . /script.php

Map any request to a handler

In the case where all URIs should be sent to the same place (including potentially requests for static content) the method to use depends on the type of the handler. For php scripts, use: For other handlers such as php scripts, use:

RewriteCond %{REQUEST_URI} !=/script.php
RewriteRule .* /script.php

And for CGI scripts:

ScriptAliasMatch .* /var/www/script.cgi

Map URIs corresponding to existing files to a handler instead

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f
RewriteCond %{REQUEST_URI} !=/script.php
RewriteRule .* /script.php

If the existing files you wish to have handled by your script have a common set of file extensions distinct from that of the hander, you can bypass mod_rewrite and use instead mod_actions. Let’s say you want all .html and .tpl files to be dealt with by your script:

Action foo-action /script.php
AddHandler foo-action html tpl

Deny access if var=val contains the string foo.

RewriteCond %{QUERY_STRING} foo
RewriteRule ^/url - [F]

Removing the Query String

RewriteRule ^/url /url?

Adding to the Query String

Keep the existing query string using the Query String Append flag, but add var=val to the end.

RewriteRule ^/url /url?var=val [QSA]

Rewriting For Certain Query Strings

Rewrite URLs like https://google.com/url1?var=val to https://google.com/url2?var=val but don’t rewrite if val isn’t present.

RewriteCond %{QUERY_STRING} val
RewriteRule ^/url1 /url2

Modifying the Query String

Change any single instance of val in the query string to other_val when accessing /path. Note that %1 and %2 are back-references to the matched part of the regular expression in the previous RewriteCond.

RewriteCond %{QUERY_STRING} ^(.*)val(.*)$
RewriteRule /path /path?%1other_val%2

Disable browser caching for all files that don’t get a hash string by Angular.

<FilesMatch "^(?!.*\.([0-9a-z]{20})\.).*$">
<IfModule mod_headers.c>
FileETag None
Header unset ETag
Header unset Pragma
Header unset Cache-Control
Header unset Last-Modified
Header set Pragma "no-cache"
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Expires "Mon, 1 Jan 1900 00:00:00 GMT"
</IfModule>

</FilesMatch>

<IfModule mod_headers.c>

Remove X-Powered-By header

<IfModule mod_headers.c>
Header unset X-Powered-By
Header always unset X-Powered-By
</IfModule>

Remove server signature

ServerSignature Off

This is a fairly simple RewriteRule. Use the expression (-4)? to optionally match the -4 and redirect it to /blog-5 along with requests to /blog/. The second (.*) group after the / captures everything else into $2.

RewriteEngine On
RewriteRule ^blog(-4)?/(.*) blog-5/$2 [L]

The above will do a silent internal rewrite. If you actually want to redirect and have the browser the new URL, change [L] to [L,R=301].

Note: Realizing blog-4 is probably a variable name, use (-.+)? to match anything. But you also need a RewriteCond so it doesn’t match blog-5:

RewriteCond %{REQUEST_URI} !^/blog-5
RewriteRule ^blog(-.+)?/(.*) blog-5/$2 [L]

Forcing Non-WWW with HTTPS Site Addresses

When you add this information to your .htaccess file, any visitors who type in www.huyhoa.net will be sent to huyhoa.net.

Options +FollowSymLinks
RewriteEngine on
RewriteCond %{SERVER_PORT} 80 [OR]
RewriteCond %{HTTP_HOST} ^www.huyhoa.net [NC]
RewriteRule ^(.*)$ https://huyhoa.net/$1 [R,L]

Replace huyhoa.net with your domain.

Forcing WWW with HTTPS Site Addresses with .htaccess

Options +FollowSymLinks
RewriteEngine on
RewriteCond %{SERVER_PORT} 80 [OR]
RewriteCond %{HTTP_HOST} !^www.huyhoa.net [NC]
RewriteRule ^(.*)$ https://www.huyhoa.net/$1 [R,L]

Remember to replace huyhoa.net with your domain.

Creating a Custom 404 Error Page with .htaccess

# serve custom error pages
ErrorDocument 404 /errors/400.html

You can change any error page using the .htaccess file.
For example:

# serve custom error pages
ErrorDocument 400 /errors/400.html
ErrorDocument 401 /errors/401.html
ErrorDocument 402 /errors/402.html
ErrorDocument 403 /errors/403.html
ErrorDocument 404 /errors/404.html
ErrorDocument 405 /errors/405.html
ErrorDocument 408 /errors/408.html
ErrorDocument 500 /errors/500.html
ErrorDocument 501 /errors/501.html
ErrorDocument 503 /errors/503.html
ErrorDocument 508 /errors/508.html

See all list of HTTP status codes here: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes

Denying and Allowing Access

Deny except specific IPs

Order deny,allow
Deny from all
Allow from 1.1.1.1
Allow from 2.2.2.2

Allow except specific IPs

Order deny,allow
Allow from all
Deny from 1.1.1.1
Deny from 2.2.2.2

Set Expires

# BEGIN EXPIRES
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 10 days"
ExpiresByType text/css "access plus 1 week"
ExpiresByType text/plain "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType application/x-javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 week"
ExpiresByType application/x-icon "access plus 1 year"
</IfModule>
# END EXPIRES

Temporary Maintenance using Mod_Rewrite

# Don't forget to turn on the rewrite engine
RewriteEngine on
# Maintenance Redirection
# Replace 1\.1\.1\.1 with your own IP address
# Uncomment first conditional to turn off the redirection
# RewriteCond %{REQUEST_URI} ^$a

RewriteCond %{REQUEST_URI} !maintenance.html
RewriteCond %{REQUEST_FILENAME} !(styles|images).+$
RewriteCond %{REMOTE_ADDR} !^1\.1\.1\.1$
RewriteCond %{REMOTE_ADDR} !^127\.0\.0\.1$
RewriteRule (.*) /maintenance.html [R,L]

Prevent Image Hotlinking

<IfModule mod_rewrite.c>
Options -Indexes
Options +FollowSymLinks

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^https://(.+\.)?www\.SITE-NAME\.DOMAIN/ [NC]
RewriteCond %{HTTP_REFERER} !^https://(.+\.)?yandex\.(.+)/ [NC]
RewriteCond %{HTTP_REFERER} !^https://(.+\.)?rambler\.(.+)/ [NC]
RewriteCond %{HTTP_REFERER} !^https://(.+\.)?google\.(.+)/ [NC]
RewriteCond %{HTTP_REFERER} !^https://(.+\.)?(.*\.)?google\.(.+)/ [NC]
RewriteCond %{HTTP_REFERER} !^https://(.+\.)?bing\.(.+)/ [NC]
RewriteCond %{HTTP_REFERER} !^https://(.+\.)?(.*\.)?bing\.(.+)/ [NC]
RewriteCond %{HTTP_REFERER} !^https://(.+\.)?yahoo\.(.+)/ [NC]
RewriteCond %{HTTP_REFERER} !^https://(.+\.)?(.*\.)?yahoo\.(.+)/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule .*\.(swf|jp?g|ti?f|gif|gif|bmp|png|pdf|mp3|wav|wmv|avi|mpeg|ogg)$ https://www\.SITE-NAME\.DOMAIN/image\.png [L]
</IfModule>

Redirect a Single Page

Redirect 301 /oldpage.html https://www.example.com/newpage.html
Redirect 301 /oldpage2.html https://www.example.com/folder/

Redirect Using RedirectMatch

RedirectMatch 301 /subdirectory(.*) https://www.google.com/ads/$1
RedirectMatch 301 ^/(.*).htm$ /$1.html
RedirectMatch 301 ^/200([0-9])/([^01])(.*)$ /$2$3
RedirectMatch 301 ^/category/(.*)$ /$1
RedirectMatch 301 ^/(.*)/the-top-best-vietnam-tourist-destination.html(.*) /vietnam-tourist-destination.html
RedirectMatch 301 ^/(.*).html/1/(.*) /$1.html$2
RedirectMatch 301 ^/manual/(.*)$ https://www.php.net/manual/$1
RedirectMatch 301 ^/dreamweaver/(.*)$ /tools/$1
RedirectMatch 301 ^/community/(.*)$ https://community.cloudflare.com/$1

Alias a Single Directory

RewriteEngine On
RewriteRule ^source-directory/(.*) /target-directory/$1 [R=301,L]

Redirect an Entire Site

Redirect 301 / https://newsite.com/

Exclude URL from Redirection
This snippet allows you to exclude a URL from redirection. For example, if you have redirection rules set up but want to exclude robots.txt so search engines can access that URL as expected.

RewriteEngine On
RewriteRule ^robots.txt[L]

Deny Access to Hidden Files and Directories

Hidden files and directories (those whose names start with a dot .) should most, if not all, of the time, be secured. For example: .htaccess, .htpasswd, .git, .hg…

RewriteCond %{SCRIPT_FILENAME} -d [OR]
RewriteCond %{SCRIPT_FILENAME} -f
RewriteRule "(^|/)\."[F]

Alternatively, you can just raise a “Not Found” error, giving the attacker no clue:

RedirectMatch 404 /\..*$

Deny Access to Backup and Source Files

These files may be left by some text/HTML editors (like Vi/Vim) and pose a great security danger if exposed to the public.

<FilesMatch "(\.(bak|config|dist|fla|inc|ini|log|psd|sh|sql|swp)|~)$">
## Apache 2.2
Order allow,deny
Deny from all
Satisfy All

## Apache 2.4
# Require all denied
</FilesMatch>

Disable Directory Browsing

Options All -Indexes

Performance

Compress Text Files

<IfModule mod_deflate.c>

# Force compression for mangled headers.
# https://developer.yahoo.com/blogs/ydn/pushing-beyond-gzipping-25601.html
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
</IfModule>
</IfModule>

# Compress all output labeled with one of the following MIME-types
# (for Apache versions below 2.3.7, you don't need to enable `mod_filter`
# and can remove the `<IfModule mod_filter.c>` and `</IfModule>` lines
# as `AddOutputFilterByType` is still in the core directives).
<IfModule mod_filter.c>
AddOutputFilterByType DEFLATE application/atom+xml \
application/javascript \
application/json \
application/rss+xml \
application/vnd.ms-fontobject \
application/x-font-ttf \
application/x-web-app-manifest+json \
application/xhtml+xml \
application/xml \
font/opentype \
image/svg+xml \
image/x-icon \
text/css \
text/html \
text/plain \
text/x-component \
text/xml
</IfModule>

</IfModule>

Set Expires Headers

Expires headers tell the browser whether they should request a specific file from the server or just grab it from the cache. It is advisable to set static content’s expires headers to something far in the future.

If you don’t control versioning with filename-based cache busting, consider lowering the cache time for resources like CSS and JS to something like 1 week. Source

<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 1 month"

# CSS
ExpiresByType text/css "access plus 1 year"

# Data interchange
ExpiresByType application/json "access plus 0 seconds"
ExpiresByType application/xml "access plus 0 seconds"
ExpiresByType text/xml "access plus 0 seconds"

# Favicon (cannot be renamed!)
ExpiresByType image/x-icon "access plus 1 week"

# HTML components (HTCs)
ExpiresByType text/x-component "access plus 1 month"

# HTML
ExpiresByType text/html "access plus 0 seconds"

# JavaScript
ExpiresByType application/javascript "access plus 1 year"

# Manifest files
ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds"
ExpiresByType text/cache-manifest "access plus 0 seconds"

# Media
ExpiresByType audio/ogg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType video/mp4 "access plus 1 month"
ExpiresByType video/ogg "access plus 1 month"
ExpiresByType video/webm "access plus 1 month"

# Web feeds
ExpiresByType application/atom+xml "access plus 1 hour"
ExpiresByType application/rss+xml "access plus 1 hour"

# Web fonts
ExpiresByType application/font-woff2 "access plus 1 month"
ExpiresByType application/font-woff "access plus 1 month"
ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
ExpiresByType application/x-font-ttf "access plus 1 month"
ExpiresByType font/opentype "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
</IfModule>

Set PHP Variables

php_value <key> <val>

# For example:

php_value upload_max_filesize 50M
php_value max_execution_time 240

 

References:

5/5 - (1 vote)
Wordpress
Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
Previous Article70+ beautiful summer hairstyles [with photo] that never stop being hot
Next Article 30+ Useful Custom WooCommerce Functions for Your WordPress Site
Huy Hoa
  • Website

In Case You Missed It

PHP Foreach Loop Tutorial: Syntax, Examples, and Best Practices
A Guide to get_post_meta() Function in WordPress
Master WP Cron: A Comprehensive Guide to Scheduling, Troubleshooting, and Optimization
The 41+ best free and premium WooCommerce themes
30+ Useful Custom WooCommerce Functions for Your WordPress Site
How to get post data in WordPress?
How to Use Woocommerce_form_field() Function with 16 Examples
5 examples of getting Post by ID & 11 Ways to Get Post ID in WordPress
These 70+ Specialized Blogs About WordPress Will Help Bloggers Succeed

Leave A Reply Cancel Reply

Search
Wordpress Themes & Plugins

How to Fix PhpMyAdmin Error Incorrect Format Parameter

PhpMyAdmin Error – incorrect format parameter might appear on multiple hosting platforms like shared hosting, VPS, localhost, or Dedicated Server. You may get incorrect format…

These 70+ Specialized Blogs About WordPress Will Help Bloggers Succeed

How to Use Woocommerce_form_field() Function with 16 Examples

PHP Foreach Loop Tutorial: Syntax, Examples, and Best Practices

The 41+ best free and premium WooCommerce themes

wp_get_attachment_image_src() – a WordPress Function to Returns Array of Image Data

Optimize performance and security for WordPress using .htaccess

Trending
Vietnam

Tet 2026: Everything You Need to Know About the Vietnamese Lunar New Year

Tet, the Vietnamese Lunar New Year, is the most important and widely celebrated holiday in…

PHP Foreach Loop Tutorial: Syntax, Examples, and Best Practices

Rash vs. Hives: How to Identify and Treat Them Naturally

How to Get Rid of a Pimple Inside Your Nose: A Comprehensive Guide

Ear Hygiene: How to Clean Your Ears the Right Way

Triangle Face Shapes Guide: Hairstyles, Glasses & Makeup Tips

Vietnamese New Year Traditions

© 2025 All Rights Reserved  by  HuyHoa.Net. DMCA.com Protection Status .
Hosted by Dreamhost. Follow us on  Google News.
  • About Us
  • Privacy Policy
  • Cookie Policy
  • Contact Us

Type above and press Enter to search. Press Esc to cancel.