Uses of the .htaccess file in web hosting

The .htaccess file is present in Apache and Litespeed web server environments (but not Nginx). This file, although small is very powerful and can be used to achieve a range of objectives and allows you to make changes to the server’s behaviour for a specific directory without editing the main server configuration files. This article covers some of the things you can achieve using the .htaccess file. All web hosting packages provided by netnerd.com provide website file access to allow you to manage or change your website’s .htaccess file.

What is an .htaccess file?

An .htaccess file is a configuration file used by the Apache web server to apply rules and settings to the directory it’s placed in, and all directories beneath it.

These rules can control things like access permissions, redirects, security policies, and performance features.

The .htaccess file allows website owners to modify server behaviour without touching the main Apache configuration.

Where do I find or put the .htaccess file?

The .htaccess file is usually found in the document root directory of your website (for example, /public_html/ or /www/). If it doesn’t already exist, you can create one using a plain text editor.

Make sure the file is named exactly .htaccess (with a dot at the start and no extension). Upload it to the directory where you want the rules to apply, usually the document root.

There’s already things in my .htaccess file, do I need to leave these?

Yes. Often, content management systems like WordPress generate their own .htaccess rules, especially for things like pretty permalinks. You should not delete or overwrite these without understanding what they do.

If you’re adding your own rules, always place them above or below existing ones, with a clear comment to explain what your new rule does.

The sequential nature of .htaccess

Apache processes .htaccess files from top to bottom, so the order of your rules matters. If two rules conflict, the first one takes precedence. Always structure your rules carefully and test them after adding.

Uses of the .htaccess file for all websites

The following can be used on all types of websites, when operating in an Apache or Litespeed environment.

Deny all

Code:

deny from all

Why you’d use deny all

Blocks access to all visitors. Useful in maintenance mode or when protecting sensitive directories (like a backup folder).

Implications of using deny all

Nobody, including you, will be able to access the directory unless further rules are added to allow specific IPs. Using deny all displays a 403 error (forbidden) to all site visitors.

You might use a deny all rule to take a website offline. You might do this if you’ve only partially made a website and don’t want people to see it until it’s finished.

Deny all except yourself

Code (when 123.456.789.000 is your public facing IP address):

order deny,allow
deny from all
allow from 123.456.789.000

Why you might deny all except yourself

Allows only your IP to access the directory (or website as a whole). Great for admin areas or testing/development environments.

Implications of using deny all except yourself

Only the IP listed will have access. If your IP changes, you’ll lock yourself out. You might use this to allow yourself to see and work on a website, while the rest of the world instead is served a 403 error.

You could use this when creating a website to allow yourself access while the website is developed, and preventing the rest of the world from seeing an incomplete website.

Disable or enable directory browsing

Code to disable directory browsing:

Options -Indexes

Code to enable (not recommended unless needed) directory browsing:

Options +Indexes

Why you’d disable directory browsing

Disabling prevents visitors from seeing a file listing if no index file is present. This stops people from being able to browse the file structure of your website.

Implications of disabling directory browsing: Increases security by not exposing file structure. Enabling it may leak sensitive files.

Why you’d enable directory browsing

You’d only need to enable directory browsing if you need to allow people to access the file system of your website. This isn’t generally a good idea, but you might need to do this if you’re doing something like storing documentation in your website’s file system and providing customers with links to the directories containing this documentation.

Implications of enabling directory browsing

Decreases security by exposing file structure. May leak sensitive files.

Redirects

Code (permanent redirect):

Redirect 301 /old-page.html https://example.com/new-page.html

Why you’d use a redirect

Useful for SEO when pages move or URLs change. Although syntax can vary, these rules can be used to effectively inform search engine crawlers that an old page has been replaced by a new page.

Implications of using a redirect

Helps to preserve search engine rankings. Mistyped rules may break links or cause redirect loops.

Caching policy

Code example:

<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType text/css "access plus 1 month"
</IfModule>

Code full caching policy:

<IfModule mod_expires.c>
  ExpiresActive On

 # Images
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/gif "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
  ExpiresByType image/webp "access plus 1 year"
  ExpiresByType image/svg+xml "access plus 1 year"
  ExpiresByType image/x-icon "access plus 1 year"

  # Video
  ExpiresByType video/webm "access plus 1 year"
  ExpiresByType video/mp4 "access plus 1 year"
  ExpiresByType video/mpeg "access plus 1 year"

  # Fonts
  ExpiresByType font/ttf "access plus 1 year"
  ExpiresByType font/otf "access plus 1 year"
  ExpiresByType font/woff "access plus 1 year"
  ExpiresByType font/woff2 "access plus 1 year"
  ExpiresByType application/font-woff "access plus 1 year"
  ExpiresByType application/font-woff2 "access plus 1 year"

  # CSS, JavaScript
  ExpiresByType text/css "access plus 1 year"
  ExpiresByType text/javascript "access plus 1 year"
  ExpiresByType application/javascript "access plus 1 year"

  # Others
  ExpiresByType application/pdf "access plus 1 year"
  ExpiresByType image/vnd.microsoft.icon "access plus 1 year"
</IfModule>

Why you’d use a caching policy

Speeds up repeat visits by telling browsers to cache static resources. The directives above are used to tell browsers which types of resources should be cached, and for how long they should be cached.

Implications of using a caching policy

Improves performance, but users may not see updates until cache expires. By locally caching resources browser can load them locally in a faster time than it would take to request and obtain them from your website. The reduced time can have a positive effect on page load times.

If a resources that’s been cached has been changed or updated, the browser’s cache will either need to be cleared or organically expire for the respective change or update to be seen.

Gzip compression

Example gzip compression code:

<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript
</IfModule>

Full example of gzip compression code:

<IfModule mod_deflate.c>
  # Compress HTML, CSS, JavaScript, Text, XML and fonts
  AddOutputFilterByType DEFLATE application/javascript
  AddOutputFilterByType DEFLATE application/rss+xml
  AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
  AddOutputFilterByType DEFLATE application/x-font
  AddOutputFilterByType DEFLATE application/x-font-opentype
  AddOutputFilterByType DEFLATE application/x-font-otf
  AddOutputFilterByType DEFLATE application/x-font-truetype
  AddOutputFilterByType DEFLATE application/x-font-ttf
  AddOutputFilterByType DEFLATE application/x-javascript
  AddOutputFilterByType DEFLATE application/xhtml+xml
  AddOutputFilterByType DEFLATE application/xml
  AddOutputFilterByType DEFLATE font/opentype
  AddOutputFilterByType DEFLATE font/otf
  AddOutputFilterByType DEFLATE font/ttf
  AddOutputFilterByType DEFLATE image/svg+xml
  AddOutputFilterByType DEFLATE image/x-icon
  AddOutputFilterByType DEFLATE text/css
  AddOutputFilterByType DEFLATE text/html
  AddOutputFilterByType DEFLATE text/javascript
  AddOutputFilterByType DEFLATE text/plain
  AddOutputFilterByType DEFLATE text/xml

  # Remove browser bugs (only needed for really old browsers)
  BrowserMatch ^Mozilla/4 gzip-only-text/html
  BrowserMatch ^Mozilla/4\.0[678] no-gzip
  BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
  Header append Vary User-Agent
</IfModule>

Why you’d used gzip compression

Compresses files before sending to browser, reducing load times. Compressed files are smaller in size, so they take less time to transfer over the network. This can help reduce the overall amount of data transferred when a page loads, and reduce page load times.

Implications of using gzip compression

Improved performance can be gained when using gzip compression. Gzip compression must be supported by the browser, which all modern browsers do.

Security headers

Example code:

<IfModule mod_headers.c>
  Header set X-Content-Type-Options "nosniff"
  Header set X-Frame-Options "SAMEORIGIN"
  Header always set Referrer-Policy "no-referrer-when-downgrade"
</IfModule>

Why you might use security headers

Adds extra protection against common attacks like clickjacking or content spoofing.

Implications of using security headers

Strengthens security, but some headers can interfere with embedded content if not configured correctly. Security header generators can be used to tailor security headers to your website’s operation.

Define the file used as the homepage

Example code:

DirectoryIndex home.html

The rule above makes home.html load as your website’s homepage.

Why you might need to define the file used as the homepage

Specifies which file should load when someone visits a directory.

Implications of defining the file used as the homepage

Useful if your homepage isn’t named index.html or index.php.

WordPress specific security rules.

It’s possible to use rules in the .htaccess file to harden your WordPress website. As all requests to your WordPress website are rewritten to the index.php file in your domain’s document root, there aren’t many cases when php files will need to be accessed directly.

Protecting WordPress system files

Protecting WordPress system files code example:

RewriteRule ^wp-admin/install\.php$ - [F]
RewriteRule ^wp-admin/includes/ - [F]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F]
RewriteRule ^wp-includes/theme-compat/ - [F]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule (^|.*/)\.(git|svn)/.* - [F]

These .htaccess rules are designed to block access to sensitive WordPress core files and directories, helping to prevent attacks, information disclosure, and unauthorised access.

A break down what the WordPress system files rules above does

RewriteRule ^wp-admin/install\.php$ - [F]

What it does:
Blocks direct access to wp-admin/install.php.

Why:
This file is used during WordPress installation. After setup, it’s no longer needed and could be abused to reinitialise or tamper with the installation.

Implication:
Prevents reinstallation abuse. No legitimate user should need to access this post-install.

RewriteRule ^wp-admin/includes/ - [F]

What it does:
Blocks access to everything under the wp-admin/includes/ directory.

Why:
This folder contains helper PHP scripts used by WordPress internally in admin pages. They should never be directly accessed.

Implication:
Protects sensitive logic files from being misused or exposed.

RewriteRule !^wp-includes/ - [S=3]

What it does:
This is a skip rule. If the URL does not start with wp-includes/, skip the next 3 rules.

Why:
Optimises rule processing. The next three rules only matter for requests targeting the wp-includes/ folder. If it’s not that, no need to check further.

Implication:
Improves performance and clarity by only applying the next few security rules to relevant requests.

RewriteRule ^wp-includes/[^/]+\.php$ - [F]

What it does:
Blocks direct access to PHP files in the wp-includes/ folder (but not subfolders).

Why:
These files are core libraries and are never meant to be accessed directly via URL.

Implication:
Prevents attackers from triggering or probing core PHP functionality.

RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F]

What it does:
Blocks access to any .php file in wp-includes/js/tinymce/langs/.

Why:
Historically, this path has been abused to inject malicious scripts or exploit vulnerabilities.

Implication:
Hardens WordPress against known attack patterns.

RewriteRule ^wp-includes/theme-compat/ - [F]

What it does:
Blocks access to the theme-compat folder inside wp-includes.

Why:
This is a fallback theme file location, not intended for direct access.

Implication:
Reduces the surface area of attack by locking down legacy theme support files.

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule (^|.*/)\.(git|svn)/.* - [F]

What it does:
The RewriteCond checks if the request is for a real file.
The RewriteRule blocks access to any .git/ or .svn/ folders.

Why:
Git and SVN are version control directories that may contain sensitive source code or credentials.

Implication:
Prevents accidental source leaks or unauthorised access to development files.

Why would the WordPress system files rules be used?

Security Hardening: Blocks known sensitive core files and directories.

Attack Surface Reduction: Limits what a hacker can directly probe or interact with.

Mitigation of Exploits: Protects against common vulnerabilities and bot scans targeting WordPress structures.

Implications of using these WordPress system files rules

Positive:

  • Improves site security significantly.
  • Blocks unnecessary and risky access.

Potential Negatives:

  • If a plugin or theme tries to access one of these paths directly (rare but possible), it may break.
  • Misconfigurations can cause false positives: e.g. blocking legitimate files.

These rules are a security enhancement meant to protect WordPress core files from external access. They’re safe for most sites and especially valuable for shared hosting environments where additional server-level protections may be limited.

Deny access to PHP files in the uploads directory and subdirectories

Deny access to PHP files in the uploads directory and subdirectories code:

RewriteRule ^wp\-content/uploads/.*\.(?:php[1-7]?|pht|phtml?|phps)\.?$ - [NC,F]

What this deny access to PHP files in the uploads directory rule does

This rule blocks access to any file in the wp-content/uploads/ directory that has an extension resembling a PHP-type script file, such as:

.php, .php1, .php2 … .php7

.pht

.phtml, .phtm

.phps

Optional trailing dot (e.g. .php.)

The flags:

NC = No Case (case-insensitive match)

F = Forbidden (return HTTP 403)

Why this deny access to PHP files in the uploads directory rule is used

The uploads folder is meant for media (images, PDFs, etc.), not scripts. However, attackers often exploit vulnerabilities to upload malicious PHP files and then execute them directly via the browser.

This rule blocks execution of those malicious files if they’re uploaded to the uploads folder—even if the attacker gives them a misleading name like backdoor.phtml or exploit.php7.

Implications of using this deny access to PHP files in the uploads directory rule

Benefits:

  • Significantly increases security.
  • Stops uploaded PHP-like files from being executed if an attacker finds an upload vulnerability.
  • Hardens one of the most vulnerable areas in WordPress.
  • The uploads directory is writeable and open by design—making it a common target.

Possible issues:

  • False positives (rare)
    • If you intentionally upload a .php or .phtml file to uploads and need it to run (which is not typical or advisable), this rule will block it.
  • Doesn’t prevent uploads, just execution.
    • This rule doesn’t stop malicious files from being uploaded, it only prevents them from being run. You still need file upload validation on the application side.

Example malicious PHP files in the uploads directory scenario

  • Attacker uploads shell.php to wp-content/uploads/shell.php
  • Then tries to run: https://example.com/wp-content/uploads/shell.php
  • This rule returns a 403 Forbidden and the script won’t execute

Deny access to PHP files in the themes directory and subdirectories

Deny access to PHP files in the themes directory and subdirectories rule:

RewriteRule ^wp\-content/themes/.*\.(?:php[1-7]?|pht|phtml?|phps)\.?$ - [NC,F]

What this deny access to PHP files in the themes directory and subdirectories rule does:

This rule blocks direct access via a web browser to any file in the wp-content/themes/ directory (and its subdirectories) that has a PHP-like extension, including:

.php, .php1, .php2, …, .php7

.pht

.phtml, .phtm

.phps

Optional trailing dot (like .php. — a common evasion trick)

The flags:

NC: Case-insensitive matching (e.g., .PHP also blocked)

F: Forbid access (returns 403 Forbidden)

Why this deny access to PHP files in the themes directory and subdirectories rule is used

The wp-content/themes/ directory holds your active and inactive theme files, including PHP templates. Normally, WordPress loads these files internally via the theme system, not through direct URL access.

This rule prevents attackers from accessing theme PHP files directly, which is a common tactic for:

  • Probing for vulnerabilities
  • Executing backdoors uploaded into a theme folder
  • Running unlinked or hidden PHP scripts

Implications of using this deny access to PHP files in the themes directory and subdirectories rule

Benefits:

  • Protects against direct execution of theme PHP files
  • Stops attackers from visiting example.com/wp-content/themes/mytheme/backdoor.php
  • Neutralises web shell access in theme directories
  • Particularly useful if an attacker has already uploaded something malicious

Possible risks:

  • False positives are rare, but possible in edge cases:
  • If a custom-built theme includes PHP files that are meant to be accessed directly, they would be blocked (e.g., a theme API endpoint not routed through functions.php)
  • Doesn’t prevent the execution of theme PHP files via WordPress itself, just direct browser access

Example malicious access to PHP files in the themes directory scenario

An attacker uploads a file: wp-content/themes/twentytwenty/shell.phtml

Tries to access it via https://example.com/wp-content/themes/twentytwenty/shell.phtml

Result: 403 Forbidden and the file won’t execute

Deny access to PHP files in the plugins includes and subdirectories

Deny access to PHP files in the plugins includes and subdirectories rule:

RewriteRule ^wp\-content/plugins/.*\.(?:php[1-7]?|pht|phtml?|phps)\.?$ - [NC,F]

What this deny access to PHP files in the plugins includes and subdirectories rule does

This rule blocks direct browser access to files in the wp-content/plugins/ directory (and all subdirectories) that have PHP-like extensions, including:

.php, .php1 to .php7

.pht

.phtml, .phtm

.phps

And optionally, a trailing dot (e.g., .php. — used in obfuscation)

Flags explained:

NC = No Case (matches .PHP, .Php, etc.)

F = Forbidden (returns 403 Forbidden)

Why this deny access to PHP files in the plugins includes and subdirectories rule is used

The wp-content/plugins/ directory contains plugin code, which WordPress loads internally via its hooks and APIs — not by direct URL access.

This deny access to PHP files in the plugins includes and subdirectories rule stops attackers from:

  • Executing malicious PHP files uploaded to plugin folders.
  • Probing plugin files directly for vulnerabilities.
  • Manually triggering plugin components by bypassing WordPress’s internal loader.

Implications of using this deny access to PHP files in the plugins includes and subdirectories rule

Benefits:

  • Prevents direct execution of PHP code in plugins (even if malicious files are injected).
  • Thwarts exploit attempts targeting known plugin file paths.
  • Reduces attack surface significantly, especially on outdated or vulnerable plugins.

Possible risks:

  • Low but possible impact on some plugins:
    • A small number of plugins may rely on direct-access PHP files (e.g., standalone endpoints, AJAX handlers, or custom API files).
    • These will return 403 Forbidden and stop working if not routed properly through admin-ajax.php or a proper hook.
  • Workaround: In such cases, you can explicitly allow the needed file before this rule using an Allow from or RewriteCond block.

Example access to PHP files in the plugins includes and subdirectories rule malicious scenario

An attacker manages to upload backdoor.php into wp-content/plugins/sample-plugin/

Tries to access it via: https://example.com/wp-content/plugins/sample-plugin/backdoor.php

Result: 403 Forbidden and access denied, script doesn’t run

Allowing access to a single php file

Allowing access to a single php file rule:

RewriteRule ^wp-content/plugins/litespeed-cache/guest\.vary\.php - [L]

What this allowing access to a single php file rule does

This rule matches requests to the specific file:
wp-content/plugins/litespeed-cache/guest.vary.php
…and applies the [L] flag.

The [L] flag means “Last” — if this rule matches, Apache stops processing any further rewrite rules for this request. It does not return an error or redirect — it simply allows the request to continue without applying any more rewrite logic afterward.

You’d use this particular rule if you’re using the WordPress specific security rules rules mentioned above and the Litespeed cache plugin in WordPress with Guest Optimisation (as this needs the guest.vary.php file to be accessible to function) enabled.

You’d need to put this rule immediately above the rule that block access to PHP in plugins. This rule allows guest.vary.php to be accessed, but the other php files in the plugins directory to remain inaccessible.

This rule can potentially be amended with a different file path to allow access to other PHP files should they need to be publicly accessible for aspects of your website to function.

Implications of using this allowing access to a single php file rule

Benefits:

  • Preserves core functionality of the LiteSpeed Cache plugin.
  • Prevents accidental 403 errors if you’re applying general security rules to plugins.
  • Ensures guest cache variation features work correctly.

Risks:

  • None, as long as LiteSpeed Cache is installed.
  • This rule does not expose anything sensitive or executable to attackers — it’s part of a controlled caching system.
  • If you remove or override this rule guest cache variation might not work properly. Some visitors may see outdated or incorrect content due to caching mismatches.

FAQ

What is an .htaccess file?

It’s a configuration file used by Apache web servers to control directory-level settings like redirects, access permissions, compression, and security rules.

Where do I put the .htaccess file?

Usually in the root directory of your website (e.g., /public_html/). You can also use it in subdirectories for more granular control.

Should I delete existing content in the .htaccess file?

No. You should preserve existing rules, especially those created by WordPress or plugins. Add new rules carefully so they don’t conflict.

Why block all access with deny from all?

It completely blocks access to a directory or file. Useful for disabling access to sensitive folders like /includes/ or configuration backups.

Why allow only my IP with .htaccess?

It restricts access to a specific file or area to your own IP address. This is commonly used to protect admin tools or development environments.

What does disabling directory browsing do?

Prevents Apache from listing all files in a directory when there’s no index file. This is a privacy and security measure.

Why set up redirects in .htaccess?

To direct users (and search engines) from one URL to another. It’s often used for SEO, handling broken links, or migrating URLs.

What does .htaccess caching policy do?

You can define how long browsers should cache different file types. This improves speed and reduces bandwidth.

What is gzip compression in .htaccess?

It compresses text-based files (HTML, CSS, JS) before sending them to the browser, improving page load speed.

Why add security headers in .htaccess?

Headers like X-Frame-Options, Content-Security-Policy, and X-Content-Type-Options protect against various web attacks.

Why change the homepage using .htaccess?

You can set a custom default file to load when someone visits a directory, like home.html instead of index.html.

Why block PHP files in wp-content/uploads?

This directory should only store images and media. Blocking .php prevents execution of uploaded malware.

Why block PHP files in wp-content/themes?

Themes shouldn’t expose their internal files to browsers. Blocking direct access protects against backdoors in themes.

Why block PHP files in wp-content/plugins?

Direct access to plugin PHP files can be risky. This rule protects against triggering vulnerable scripts manually.

What does the rule blocking install.php and includes in wp-admin do?

It prevents direct access to install.php and internal admin scripts, which could otherwise be abused or exposed if misconfigured.

What does this line do: RewriteRule !^wp-includes/ – [S=3]?

It skips the next 3 rules unless the request is to wp-includes/. This improves performance and ensures other rules don’t fire unnecessarily.

What does the rule blocking files in wp-includes do?

It stops access to specific core WordPress files and folders that should never be accessed directly from the browser.

What does the rule blocking .git or .svn do?

It protects version control directories, which may expose your codebase or credentials if publicly accessible.

Why allow guest.vary.php in LiteSpeed Cache?

This file is required by LiteSpeed to manage guest cache variations. The rule allows it to function without interference from other security rules.

Similar Posts

Leave a Reply