Modus Internet : Located in Vancouver and Burnaby British Columbia we do website design, database integration, custom programming, search engine optimization (SEO) or consultation.
Current Location: Home / Products / Custodian CMS / .htaccess


Security is very important to the developers of Custodian CMS (CCMS) and because this product is Open-source it is even more important that we get it right the first time. Besides using best-of-practice database integration methods and extensive testing CCMS contains a rigid .htaccess file to help protect your site from the bad guys.

Below is the /.htaccess file bundled with Custodian CMS v0.6.1. It is self contained and requires no configuration accept perhaps a minor tweak to the 'SetEnv TZ' setting on line 58 if desired. If your considering using CCMS on a GoDaddy maintained server there are other settings that will be necessary to tweak, read below for more information.

# If you are attempting to use Custodian CMS on a GoDaddy hosted service you might experience problems getting
# the templates to work properly.  Try doing the following in the code below these comments:
# Uncomment: SetEnv HTTP_MOD_REWRITE On
# Comment: FileETag MTime Size
# Comment: php_flag register_globals off
# Comment: php_flag magic_quotes_gpc off

# To enable Mod Rewrite on GoDaddy servers uncomment the following code.

# The ETag or entity tag provides web cache validation.  If you are trying to install Custodian CMS on a
# GoDaddy server comment out the line of code below, GoDaddy seems to have Etag support already enabled.
#FileETag MTime Size

# Bad Request
ErrorDocument 400 /index.php?ccms_tpl=error400

# Forbidden
ErrorDocument 403 /index.php?ccms_tpl=error403
#ErrorDocument 403 /index.php?ccms_tpl=search

# Not Found
ErrorDocument 404 /index.php?ccms_tpl=error404

# Internal Server Error
ErrorDocument 500 /index.php?ccms_tpl=error500

# Disable your Apache version number from showing up in HTTP headers for added security.
ServerSignature Off

# Prevent people from being able to see the directory of folders that do not contain an index file.
Options -Indexes

Options +FollowSymLinks

Options -Multiviews

<Files .htaccess>
	# Prevent viewing of .htaccess file.
	order allow,deny
	deny from all

<IfModule mod_access.c>
	# Set timezone for your server. A list of supported timezone can be found at
	SetEnv TZ America/Vancouver

	# Do Not Track: Universal Third-Party Web Tracking Opt Out

	# Protect against Apache HTTP Server Denial Of Service Vulnerability.  CVE-2011-3192
	SetEnvIf Range (,.*?){5,} bad-range=1
	RequestHeader unset Range env=bad-range

<IfModule mod_headers.c>
	# Disable your PHP version number from showing up in HTTP headers for added security.
	Header unset X-Powered-By

	# Don't allow any pages to be framed - Defends against CSRF
	Header set X-Frame-Options DENY

	# Turn on IE8-IE9 XSS prevention tools
	Header set X-XSS-Protection "1; mode=block"

	# Prevent mime based attacks
	Header set X-Content-Type-Options "nosniff"

	# Use this to force IE to hide that annoying browser compatibility button in the address bar.
	# IE=edge means IE should use the latest (edge) version of its rendering engine.
	BrowserMatch MSIE ie
	Header set X-UA-Compatible "IE=edge"

<IfModule mod_rewrite.c>
	RewriteEngine on
	RewriteBase /

	# If we managed to get passed all those rules then the next step is to call the correct template on the server and
	# start producing output, but first lets make sure the php environment is setup the way we like it first.
	# Comment the two lines of code out below if experiencing problems on a GoDaddy hosted services.
	#php_flag register_globals off
	# magic_quotes_gpc are DEPRECATED and will eventually be removed all together, best to disable them now.
	#php_flag magic_quotes_gpc off

	# Disable the HTTP TRACE Method for added security.
	RewriteRule .* - [F]

	# Block empty user agents and empty HTTP referrers.
	RewriteCond %{HTTP_REFERER} ^$ [NC]
	RewriteCond %{HTTP_USER_AGENT} ^$ [NC]
	RewriteRule .* - [F,L]

	# BOT block
	# URL encoded HTML, see
	RewriteCond %{HTTP_USER_AGENT} (<|>|'|%0A|%0D|%27|%3C|%3E|%00) [NC,OR]
	# Address harvesters
	RewriteCond %{HTTP_USER_AGENT} ^(autoemailspider|ExtractorPro) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^E?Mail.?(Collect|Harvest|Magnet|Reaper|Siphon|Sweeper|Wolf) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} (DTS.?Agent|Email.?Extrac) [NC,OR]
	RewriteCond %{HTTP_REFERER} iaea\.org [NC,OR]
	# Download managers
	RewriteCond %{HTTP_USER_AGENT} ^(Alligator|DA.?[0-9]|DC\-Sakura|Download.?(Demon|Express|Master|Wonder)|FileHound) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^(Flash|Leech)Get [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^(Fresh|Lightning|Mass|Real|Smart|Speed|Star).?Download(er)? [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^(Gamespy|Go!Zilla|iGetter|JetCar|Net(Ants|Pumper)|SiteSnagger|Teleport.?Pro|WebReaper) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^(My)?GetRight [NC,OR]
	# Image-grabbers
	RewriteCond %{HTTP_USER_AGENT} ^(AcoiRobot|FlickBot|webcollage) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^(Express|Mister|Web).?(Web|Pix|Image).?(Pictures|Collector)? [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^Image.?(fetch|Stripper|Sucker) [NC,OR]
	# "Gray-hats"
	RewriteCond %{HTTP_USER_AGENT} ^(Atomz|BlackWidow|BlogBot|EasyDL|Marketwave|Sqworm|SurveyBot|Webclipping\.com) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} (girafa\.com|gossamer\-threads\.com|grub\-client|Netcraft|Nutch) [NC,OR]
	# Site-grabbers
	RewriteCond %{HTTP_USER_AGENT} ^(eCatch|(Get|Super)Bot|Kapere|HTTrack|JOC|Offline|UtilMind|Xaldon) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^Web.?(Auto|Cop|dup|Fetch|Filter|Gather|Go|Leach|Mine|Mirror|Pix|QL|RACE|Sauger) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^Web.?(site.?(eXtractor|Quester)|Snake|ster|Strip|Suck|vac|walk|Whacker|ZIP) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} WebCapture [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^DISCo\ Pump [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^EirGrabber [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^Net\ Vampire [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^NetZIP [NC,OR]
	# Tools
	RewriteCond %{HTTP_USER_AGENT} ^(curl|Dart.?Communications|Enfish|htdig|Java|larbin) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} (FrontPage|Indy.?Library|RPT\-HTTPClient) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^(libwww|lwp|libwww-perl.*|PHP|Python|www\.thatrobotsite\.com|webbandit|Wget|Zeus) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^(Microsoft|MFC).(Data|Internet|URL|WebDAV|Foundation).(Access|Explorer|Control|MiniRedir|Class) [NC,OR]
	# Unknown
	RewriteCond %{HTTP_USER_AGENT} ^(Crawl_Application|Lachesis|Nutscrape) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^[CDEFPRS](Browse|Eval|Surf) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^(Demo|Full.?Web|Lite|Production|Franklin|Missauga|Missigua).?(Bot|Locat) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} (efp@gmx\.net|hhjhj@yahoo\.com|lerly\.net|mapfeatures\.net|metacarta\.com) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^(Industry|Internet|IUFW|Lincoln|Missouri|Program).?(Program|Explore|Web|State|College|Shareware) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^(Mac|Ram|Educate|WEP).?(Finder|Search) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^(Moz+illa|MSIE).?[0-9]?.?[0-9]?[0-9]?$ [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ^Mozilla/[0-9]\.[0-9][0-9]?.\(compatible[\)\ ] [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} NaverRobot|AhrefsBot|MJ12bot|SeznamBot [NC]
	RewriteRule .* - [F,L]

	# Stop hotlinking.
	RewriteCond %{HTTP_REFERER} !^$
	# Add to allow to pull images from the server.
	#RewriteCond %{HTTP_REFERER} !^http(s)?:// [NC]
	# Add to allow to pull images from the server.
	#RewriteCond %{HTTP_REFERER} !^http(s)?:// [NC]
	RewriteCond %{HTTP_HOST}@@%{HTTP_REFERER} !^([^@]*)@@https?://\1/.* [NC]
	RewriteRule \.(bmp|gif|jpe?g|png|swf)$ - [F,L,NC]

	# Stop file and mysql injection attacks.
	RewriteCond %{QUERY_STRING} (;|<|>|'|"|\)|%0A|%0D|%22|%27|%3C|%3E|%00).*(/\*|union|select|insert|cast|set|declare|drop|update|md5|benchmark) [NC,OR]
	RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=http:// [OR]
	RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=http%3A%2F%2F [OR]
	RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=(\.\.//?)+ [OR]
	RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=/([a-z0-9_.]//?)+ [NC,OR]
	RewriteCond %{QUERY_STRING} (localhost|loopback|127\.0\.0\.1) [NC,OR]
	RewriteCond %{QUERY_STRING} (<|>|'|%0A|%0D|%27|%3C|%3E|%00) [NC]
	RewriteRule .* - [F,L]

	# Protect against PHP-CGI Remote Code Execution Bug. CVE-2012-1823
	RewriteCond %{QUERY_STRING} ^(%2d|\-)[^=]+$ [NC]
	RewriteRule .* - [F,L]

	# Denies any POST Request using a Proxy Server. Can still access site, but not comment.  Just to be clear,
	# this doesn't really work with any proxy service that really wants to hide who they are but what the hell.
	RewriteRule .* - [F,L,NS]

	# Stop 'PHP Easter Eggs' from working,
	RewriteCond %{QUERY_STRING} \=PHP[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} [NC,OR]
	# Stop proc/self/environ?
	RewriteCond %{QUERY_STRING} proc/self/environ [OR]
	# Block out any script trying to set a mosConfig value through the URL
	RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
	# Block out any script trying to base64_encode/decode content via URL
	RewriteCond %{QUERY_STRING} base64_(en|de)code[^(]*\([^)]*\) [OR]
	## IMPORTANT: If the above line throws an HTTP 500 error, replace it with these 2 lines:
	# RewriteCond %{QUERY_STRING} base64_encode\(.*\) [OR]
	# RewriteCond %{QUERY_STRING} base64_decode\(.*\) [OR]
	# Block out any script that includes a <script> tag in URL
	RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]
	# Block out any script trying to set a PHP GLOBALS variable via URL
	RewriteCond %{QUERY_STRING} GLOBALS(=|[|\%[0-9A-Z]{0,2}) [OR]
	# Block out any script trying to modify a _REQUEST variable via URL
	RewriteCond %{QUERY_STRING} _REQUEST(=|[|\%[0-9A-Z]{0,2})
	RewriteRule .* - [F,L]

	# The following two lines of code build an environment variable that either contains nothing or an 's' to
	# indicate the server port is http or https.
	RewriteCond %{SERVER_PORT}s ^(443(s)|[0-9]+s)$
	RewriteRule ^(.*)$ - [env=variable:%2]

	# The following two lines look to see if www. is found in your URI and removes it.
	# The next two lines look to see if www. is not found if your URI and adds it.
	# Comment one set or the other out depending on your needs.
	RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
	RewriteRule ^(.*)$ http%{ENV:variable}://%1/$1 [R=301,L]
	#RewriteRule ^(.*)$ http%{ENV:variable}://%1%{REQUEST_URI} [R=301,L]
	#RewriteRule ^(.*)$ http%{ENV:variable}://%{HTTP_HOST}/$1 [R=301,L]
	#RewriteCond %{HTTP_HOST} !^www\.(.+) [NC]
	#RewriteRule ^(.*)$ http%{ENV:variable}://www.%{HTTP_HOST}/$1 [R=301,L]

	# Force all conection to https and NOT http.
	#RewriteCond %{SERVER_PORT} !^443$
	#RewriteRule (.*) https://%{SERVER_NAME}/$1 [R,L]

	# Look to see if 'user' is found at the beginning of the {REQUEST_URI}, if so send the visitor to the
	# Custodian CMS admin index template.  If you change the location of your CCMS admin directory in the
	# config you will need to make the update here by hand.
	RewriteRule ^(([a-z]{2})(-[a-z]{2})?)/user(/.*)$ /ccmsusr/index.php?ccms_lng=$1&ccms_tpl=$4 [QSA,L,NC]
	RewriteRule ^(([a-z]{2})(-[a-z]{2})?)(/([a-z0-9-_\./]*))?$ /index.php?ccms_lng=$1&ccms_tpl=$4 [QSA,L,NC]

	# The following examples will FAIL and result in /ccmstpl/error.php page being called.

	# The following examples will SUCCEED and result in /index.php successfully being called.

#<IfModule mod_expires.c>
	# Optimize default expiration time
#	ExpiresActive On

	# Default expiration: 1 hour after request
#	ExpiresDefault "access plus 1 day"

	# CSS and JS expiration: 1 week after request
#	ExpiresByType text/css "access plus 1 week"
#	ExpiresByType text/javascript "access plus 1 week"
#	ExpiresByType text/x-javascript "access plus 1 week"
#	ExpiresByType application/javascript "access plus 1 week"
#	ExpiresByType application/x-javascript "access plus 1 week"

	# Image files expiration: 1 month after request
#	ExpiresByType image/bmp "access plus 1 month"
#	ExpiresByType image/gif "access plus 1 month"
#	ExpiresByType image/jpeg "access plus 1 month"
#	ExpiresByType image/jp2 "access plus 1 month"
#	ExpiresByType image/pipeg "access plus 1 month"
#	ExpiresByType image/png "access plus 1 month"
#	ExpiresByType image/svg+xml "access plus 1 month"
#	ExpiresByType image/tiff "access plus 1 month"
#	ExpiresByType image/ "access plus 1 month"
#	ExpiresByType image/x-icon "access plus 1 month"
#	ExpiresByType image/ico "access plus 1 month"
#	ExpiresByType image/icon "access plus 1 month"
#	ExpiresByType text/ico "access plus 1 month"
#	ExpiresByType application/ico "access plus 1 month"
#	ExpiresByType image/vnd.wap.wbmp "access plus 1 month"
#	ExpiresByType application/vnd.wap.wbxml "access plus 1 month"
#	ExpiresByType application/smil "access plus 1 month"

	# Audio files expiration: 1 month after request
#	ExpiresByType audio/basic "access plus 1 month"
#	ExpiresByType audio/mid "access plus 1 month"
#	ExpiresByType audio/midi "access plus 1 month"
#	ExpiresByType audio/mpeg "access plus 1 month"
#	ExpiresByType audio/x-aiff "access plus 1 month"
#	ExpiresByType audio/x-mpegurl "access plus 1 month"
#	ExpiresByType audio/x-pn-realaudio "access plus 1 month"
#	ExpiresByType audio/x-wav "access plus 1 month"

	# Movie files expiration: 1 month after request
#	ExpiresByType application/x-shockwave-flash "access plus 1 month"
#	ExpiresByType x-world/x-vrml "access plus 1 month"
#	ExpiresByType video/x-msvideo "access plus 1 month"
#	ExpiresByType video/mpeg "access plus 1 month"
#	ExpiresByType video/mp4 "access plus 1 month"
#	ExpiresByType video/quicktime "access plus 1 month"
#	ExpiresByType video/x-la-asf "access plus 1 month"
#	ExpiresByType video/x-ms-asf "access plus 1 month"

The /ccmslib, /ccmspre and /ccmstpl folders are also protected by their own .htaccess files.

<FilesMatch ".(fla|htaccess|htm|html|ini|php|phps|tpl|txt)$">
	Order Allow,Deny
	Deny from all

With these rules in place templates in these folders can not be called directly.

Templates inside the /ccmstpl directory can only be called using correctly formatted URI's containing browser language codes supported by the site. Other wise the /ccmstpl/error403.php or /ccmstpl/error404.php template will be thrown. A 2-5 character language code followed by the 1-255 character long name of the dir and or page desired.

  • e.g.:

Contact Us

778 786 2423

1310 Fraser Ave
Port Coquitlam, BC, Canada
V3B 1M4
(10 minutes from Vancouver)

Copyright © 2017 Modus Internet. All rights reserved.