Hi there,
The htaccess directives below are intended to secure/harden WordPress.
Whilst implementing the directives, it occurred to me that a number of these may be unsupported e.g.
I would appreciate it if the wider community and/or Litespeed team can provide feedback on the directives below and whether the construct below achieves the following.
	
	
	
		
								The htaccess directives below are intended to secure/harden WordPress.
Whilst implementing the directives, it occurred to me that a number of these may be unsupported e.g.
<if></if> based on the knowledge article at https://www.litespeedtech.com/suppo...iki:config:unsupported_apache_modules_by_lsws . It isn't sufficiently clear as to if this is a complete. I have assumed it is.I would appreciate it if the wider community and/or Litespeed team can provide feedback on the directives below and whether the construct below achieves the following.
- Full support for Litespeed whilst maintaining compatability with Apache
 - Secure and if there are any additional improvements
 - Performant
 - Alternatives if there are particular directives that are not supported by Litespeed.
 
		Apache config:
	
	# BEGIN WordPress
# Instatiate “mod_rewrite” module for Apache
<IfModule mod_rewrite.c>
# Enable Rewrite module
RewriteEngine On
# Declare Rewrite base
RewriteBase /
# Ignore Rewrite condition if index.php is requested
RewriteRule ^index\.php$ - [L]
# Rewrite request if file and/or directory is not present
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
# BEGIN custom directives
# Disable directory listing
Options All -Indexes
# Limit file upload size. If you do not accept file uploads you can configure this at a minimum as per the below. The below is configured for 1MB.
# LimitRequestBody 1024000
# Configure custom error pages
# ErrorDocument 404 /notfound.php
# ErrorDocument 403 /forbidden.php
# ErrorDocument 500 /error.php
# Configure default error pages
# ErrorDocument 401 default
# ErrorDocument 403 default
# Enable Security Headers
<IfModule mod_headers.c>
    # X-Frame-Options
    Header always set X-Frame-Options "SAMEORIGIN"
    # X-XSS-Protection
    Header always set X-XSS-Protection "1; mode=block"
    # X-Content-Type-Options
    Header always set X-Content-Type-Options nosniff
    # Referrer-Policy
    Header always set Referrer-Policy "strict-origin"
    # Content-Security-Policy
    # Header set Content-Security-Policy-Report-Only default-src 'self' 'unsafe-inline' https://fonts.googleapis.com; script-src 'self' 'unsafe-inline' https://maps.googleapis.com; frame-ancestors 'self'; block-all-mixed-content; form-action 'self'; font-src 'self' [URL]https://fonts.gstatic.com[/URL] data:; img-src 'self' https://secure.gravatar.com data:;
    Header set Content-Security-Policy default-src 'self' 'unsafe-inline' https://fonts.googleapis.com; script-src 'self' 'unsafe-inline' https://maps.googleapis.com; frame-ancestors 'self'; block-all-mixed-content; form-action 'self'; font-src 'self' [URL]https://fonts.gstatic.com[/URL] data:; img-src 'self' https://secure.gravatar.com data:;
    # Feature Policy
    Header set Feature-Policy "geolocation 'none'; midi 'none'; camera 'none'; usb 'none'; magnetometer 'none'; accelerometer 'none'; vr 'none'; speaker 'none'; ambient-light-sensor 'none'; gyroscope 'none'; microphone 'none'"
    # Unset headers revealing versions strings
    Header unset X-Powered-By
    Header unset X-Pingback
    Header unset SERVER
    # Disable Entity Tag Header
    Header unset ETag
    FileETag None
    #Set secure cookies
    Header always edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure;SameSite=Strict
    # Set Keep Alive Header
    Header set Connection keep-alive
    # Instructs the proxy to store both a compressed and uncompressed version of the resource
    <FilesMatch ".(js|css|xml|gz|html|woff|woff2|ttf)$">
      Header append Vary: Accept-Encoding
    </FilesMatch>
</IfModule>
# Protect number of important WordPress and web server files such as config, ini and log files (this also includes wp-config.php etc)
<FilesMatch "^(wp-config\.php|wp-mail\.php|repair\.php|xmlrpc\.php|php\.ini|php5\.ini|install\.php|php\.info|readme\.html|bb-config\.php|\.htaccess|\.htpasswd|error_log|error\.log|PHP_errors\.log|\.svn|\.log|\.bak|wlwmanifest.xml|\..*)">
  Require all denied
</FilesMatch>
# Prevent WordPress usernames from enumerating
RewriteCond %{REQUEST_URI} !^/wp-admin [NC]
RewriteCond %{QUERY_STRING} ^author=\d+ [NC,OR]
RewriteCond %{QUERY_STRING} ^author=\{num [NC]
RewriteRule ^(.*)$ - [F,L]
# Block access to WordPress login page from malformed requests
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} ^(.*)?wp-login\.php(.*)$ [NC,OR]
RewriteCond %{REQUEST_URI} ^(.*)?wp-admin?(/)$ [NC]
RewriteCond %{HTTP_REFERER} !(.*)domain\.co(.*) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^-?$ [OR]
RewriteCond %{HTTP_USER_AGENT} ^.*(jorgee|morfeusfirefox\/34.0|mozilla\/4.0|firefox\/40.1).* [NC]
RewriteRule ^(.*)$ - [F,L]
# Restrict access to WordPress PHP files from plugin and theme directories
RewriteCond %{REQUEST_URI} ^(.*)?wp-content/plugins/(.*\.php)$ [NC]
RewriteRule ^(.*)$ - [F,L]
RewriteCond %{REQUEST_URI} ^(.*)?wp-content/themes/(.*\.php)$ [NC]
RewriteRule ^(.*)$ - [F,L]
# Block access to WordPress includes folder
RewriteCond %{REQUEST_URI} ^(.*)?wp-admin/includes/(.*\.php)$ [NC, OR]
RewriteCond %{REQUEST_URI} ^(.*)?wp-includes/js/tinymce/langs/(.*\.php)$ [NC, OR]
RewriteCond %{REQUEST_URI} ^(.*)?wp-includes/theme-compat/(.*\.php)$ [NC]
RewriteRule ^(.*)$ - [F,L]
<If "%{REQUEST_URI} =~ m#^(.*)?/wp-content/uploads/(.*\.txt)#">
    Require all denied
</If>
# Block Nuisance Requests
# https://perishablepress.com/block-nuisance-requests
<IfModule mod_alias.c>
# RedirectMatch 403 (?i)\.php\.suspected
# RedirectMatch 403 (?i)\.(git|well-known)
# RedirectMatch 403 (?i)apple-app-site-association
# RedirectMatch 403 (?i)/autodiscover/autodiscover.xml
  RewriteCond %{REQUEST_URI} ^(.*)?(\.php\.suspected|\.well-known|\.git|apple|autodiscover)(.*)$ [NC]
  RewriteRule ^(.*)$ - [F,L]
</IfModule>
# Blocking the »ReallyLongRequest« Bandit
# https://perishablepress.com/blocking-reallylongrequest-bandit/
<IfModule mod_rewrite.c>
    RewriteCond %{REQUEST_METHOD} .* [NC]
    RewriteCond %{THE_REQUEST}  (YesThisIsAReallyLongRequest|ScanningForResearchPurpose) [NC,OR]
    RewriteCond %{QUERY_STRING} (YesThisIsAReallyLongRequest|ScanningForResearchPurpose) [NC]
    RewriteRule ^(.*)$ - [F,L]
</IfModule>
# 6G FIREWALL/BLACKLIST
# @ https://perishablepress.com/6g/
# 6G:[QUERY STRING]
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{QUERY_STRING} (eval\() [NC,OR]
    RewriteCond %{QUERY_STRING} (127\.0\.0\.1) [NC,OR]
    RewriteCond %{QUERY_STRING} ([a-z0-9]{2000,}) [NC,OR]
    RewriteCond %{QUERY_STRING} (javascript:)(.*)(;) [NC,OR]
    RewriteCond %{QUERY_STRING} (base64_encode)(.*)(\() [NC,OR]
    RewriteCond %{QUERY_STRING} (GLOBALS|REQUEST)(=|\[|%) [NC,OR]
    RewriteCond %{QUERY_STRING} (<|%3C)(.*)script(.*)(>|%3) [NC,OR]
    RewriteCond %{QUERY_STRING} (\\|\.\.\.|\.\./|~|`|<|>|\|) [NC,OR]
    RewriteCond %{QUERY_STRING} (boot\.ini|etc/passwd|self/environ) [NC,OR]
    RewriteCond %{QUERY_STRING} (thumbs?(_editor|open)?|tim(thumb)?)\.php [NC,OR]
    RewriteCond %{QUERY_STRING} (\'|\")(.*)(drop|insert|md5|select|union) [NC]
    RewriteRule .* - [F]
</IfModule>
# 6G:[REQUEST METHOD]
<IfModule mod_rewrite.c>
    RewriteCond %{REQUEST_METHOD} ^(connect|debug|move|put|trace|track) [NC]
    RewriteRule .* - [F]
</IfModule>
# 6G:[REFERRER]
<IfModule mod_rewrite.c>
    RewriteCond %{HTTP_REFERER} ([a-z0-9]{2000,}) [NC,OR]
    RewriteCond %{HTTP_REFERER} (semalt.com|todaperfeita) [NC]
    RewriteRule .* - [F]
</IfModule>
# 6G:[REQUEST STRING]
<IfModule mod_alias.c>
    RedirectMatch 403 (?i)([a-z0-9]{2000,})
    RedirectMatch 403 (?i)(https?|ftp|php):/
    RedirectMatch 403 (?i)(base64_encode)(.*)(\()
    RedirectMatch 403 (?i)(=\\\'|=\\%27|/\\\'/?)\.
    RedirectMatch 403 (?i)/(\$(\&)?|\*|\"|\.|,|&|&?)/?$
    RedirectMatch 403 (?i)(\{0\}|\(/\(|\.\.\.|\+\+\+|\\\"\\\")
    RedirectMatch 403 (?i)(~|`|<|>|:|;|,|%|\\|\{|\}|\[|\]|\|)
    RedirectMatch 403 (?i)/(=|\$&|_mm|cgi-|muieblack)
    RedirectMatch 403 (?i)(&pws=0|_vti_|\(null\)|\{\$itemURL\}|echo(.*)kae|etc/passwd|eval\(|self/environ)
    RedirectMatch 403 (?i)\.(aspx?|bash|bak?|cfg|cgi|dll|exe|git|hg|ini|jsp|log|mdb|out|sql|svn|swp|tar|rar|rdf)$
    RedirectMatch 403 (?i)/(^$|(wp-)?config|mobiquo|phpinfo|shell|sqlpatch|thumb|thumb_editor|thumbopen|timthumb|webshell)\.php
</IfModule>
# 6G:[USER AGENT]
<IfModule mod_setenvif.c>
    SetEnvIfNoCase User-Agent ([a-z0-9]{2000,}) bad_bot
    SetEnvIfNoCase User-Agent (archive.org|binlar|casper|checkpriv|choppy|clshttp|cmsworld|diavol|dotbot|extract|feedfinder|flicky|g00g1e|harvest|heritrix|httrack|kmccrew|loader|miner|nikto|nutch|planetwork|postrank|purebot|pycurl|python|seekerspider|siclab|skygrid|sqlmap|sucker|turnit|vikspider|winhttp|xxxyy|youda|zmeu|zune) bad_bot
# Block IPs with 6G Firewall
# https://perishablepress.com/block-ips-6g-firewall/
    # Apache < 2.3
    <IfModule !mod_authz_core.c>
        Order Allow,Deny
        Allow from all
        Deny from env=bad_bot
    </IfModule>
    # Apache >= 2.3
    <IfModule mod_authz_core.c>
        <RequireAll>
            Require all Granted
            Require not env bad_bot
        </RequireAll>
    </IfModule>
</IfModule>
# END custom directives
	
								
									Last edited by a moderator: