Using .htaccess to restrict access

This is an example .htaccess file that can be used to restrict outside (anonymous) access to your Piwik installation. Use in conjunction with the HttpAuthLogin plugin.

# Sample .htaccess file for your web document root

# Restrict outside access
AuthUserFile /absolute_path_to_a_secure_folder/.htpasswd
AuthGroupFile /dev/null
AuthName "Piwik"
AuthType Basic

<Files "*">
    Require valid-user
</Files>

<Files ~ "^piwik\.(js|php)|robots\.txt$">
    Allow from all
    Satisfy any
</Files>

# Disable session auto-start; incompatible with Zend_Session.
php_flag session.auto_start off

# Disable directory viewing.
Options -All

Here’s a variation using IP addresses and host names.

<Files "*">
    Order deny, allow
    Deny from all
    Allow from 128.252.135.
    Allow from .mydomain.com
    Allow from host.mydomain.com
</Files>

<Files ~ "^piwik\.(js|php)|robots\.txt$">
    Allow from all
    Satisfy any
</Files>

its amazing what you can do with .htaccess.
I really need to learn about that file for my site.

nice, does anyone know how to give a default-user to the htaccess field? It would be the best if it would be prefilled with a username and you only had to type in you password. thx

How does that work with a dynamic IP address?

Request for code Redirect please.

It would be the best if it would be prefilled with a username and you only had to type in you password. thanks.

What would be the best way to add SSL redirection?

<FilesMatch index.php>

doesn’t work if someones uses http:// domain.com/ instead of http:// Domain.com

hi interfaSys,…
nice helps,…this code is very useful one and fix this error,…
This work in constant progress is some collected wisdom, stuff I’ve learned on the topic of .htaccess hacking, commands I’ve used successfully in the past, on a variety of server setups, and in most cases still do. You may have to tweak the examples some to get the desired result, though, and a reliable test server is a powerful ally, preferably one with a very similar setup to your “live” server. Okay, to begin…
thanks,…

its pretty simple, to protect a folder, you simply:

AuthUserFile /full/path/to/.htpasswd
AuthType Basic
AuthName "My Secret Folder"
Require valid-user

to protect a file, you simply:

AuthUserFile /full/path/to/.htpasswd
AuthType Basic
AuthName “My Secret Page”

<Files “mypage.html”>
Require valid-user

In Piwik 1.1, there’s a force_ssl_login setting that can be set in config.ini.php.

There is a problem using this snippet while the API is working. I’ve tried to activate the wordpress-plugin WP-Piwik (http://wordpress.org/extend/plugins/wp-piwik/), but it couldn’t accept the auth-procedure (with Piwik-URL and the AuthToken). I’ve deleted this .htaccess-Part and now everything works fine. Ist there a possibility to work both? htaccess restriction AND the Api? Thx a lot!

In 1.1 is an opt-out-site available - that is blocked by htaccess, too :-/

I added this part to my htaccess:

RewriteEngine on
RewriteCond %{REMOTE_ADDR} !( my.IP)
RewriteCond %{QUERY_STRING} !(module=CoreAdminHome&action=optOut)
RewriteRule index.php - [F]

1 - turning rewrite on
2 - let me in with my IP
3 - let users in, when they want to optOut
4 - all others: send forbidden :wink:

Happy htaccessing :slight_smile:

I’m still a bit confused as to what rules I need in place. Currently I just have directory browsing disabled via: Options -All

The rules referenced above looked simplest to me, but I still had a few questions. I have piwik installed in the root of a subdomain ie http://piwik.mywebsite.com so no piwik folder, and am using it across multiple sites.

  1. So I would change <Files ~ “^piwik.(js|php)|robots.txt$”> to <Files ~ “^.(js|php)|robots.txt$”> correct?

  2. What is

Allow from .mydomain.com
Allow from host.mydomain.com

referring to exactly and is it necessary beyond the ip restriction? Do I need to add every site I’m using piwik on to the list in order for tracking to work or does the allow .js|php already take care of that?

Thank you very much for the detailed tutorial, vipsoft. This is what i’m looking for!

Hello there.

I have problems enabling this feature because the .htaccess restriction always apllies on the main page, too which obviously should be open to anybody. This might be because some other rules of my .htaccess file overrides this but these are vital and cannot be removed.

Is there ANY other solution to protect the directory?

Hello,

It looks like, even the topic is a bit older already, there is no “complete“ solution available?

  1. Some offered solutions are based on an IP adress. This is not possible for dynamic IP adresses, which is the majority here in germany. IMHO in many cases IPs are not suitable for authorization.

  2. Other solutions block everything - including the “OptOut“ command. Giving users the option to opt out is enforced by law here in germany.

From my point of view the authorization should be done directly in the index.php, not in an .htaccess. Matching acceptable commands of index.php for opt-out, guest-users etc. via RegExp in htaccess will possibly never really be invulnerable against evil guys. So I think we should combine both powers:

  1. htaccess limits access to index.php, robots.txt and whatever is absolutely neccessary. That keeps eveilguy from using vulnerable files.
  2. index.php should have an option to always check PHP_AUTH_USER except when it asks for: the hidden pixel. And opt-out.

Would you agree? Then I would make a feature request.

Bye, Jörg

This how-to is about .htaccess. Alternate auth methods are available as plugins (e.g., ldap, cas, etc).

UPDATE: This post is outdated. Please see 301 Moved Permanently below for its updated version.

Here is another example of securing your Piwik installation, based on Joomla .htaccess example under htaccess examples (security) - Joomla! Documentation, modified and adapted to Piwik. Please refer to that for additional information, if needed. The file is being used on a free shared web hoster (i.e. php.ini, etc., is not modifiable).

It does not use user or IP authentication (which could be done additionally as shown in posts above, if desired).

The assumed Piwik installation address is www.test.example.com/piwik/, with the www.test.example.com domain used exclusively for the only one Piwik installation, and the below .htaccess file placed into its main directory (i.e. above the /piwik/ directory).

###############################################################################
## .htaccess example implementation, last tested with Piwik 1.6
##
## Based on version 2.5 (proposed) of May 16th, 2011 (proposed 2.5.5 wiki doc
## history verstion by G1smd of May 17th, 2011) Joomla .haccess file
## example under http://docs.joomla.org/Htaccess_examples_%28security%29
##
###############################################################################

########## Begin - RewriteEngine enabled
RewriteEngine On
########## End - RewriteEngine enabled

########## Begin - RewriteBase
# Uncomment following line if your webserver's URL
# is not directly related to physical file paths.
# Update Your Joomla! Directory (just / for root)

#RewriteBase /
########## End - RewriteBase

########## Begin - No directory listings
## Note: +FollowSymlinks may cause problems and you might have to remove it
IndexIgnore *
Options +FollowSymLinks All -Indexes
########## End - No directory listings

########## Begin - File execution order, by Komra.de
DirectoryIndex index.php index.html
########## End - File execution order

########## Begin - ETag Optimization
## This rule will create an ETag for files based only on the modification
## timestamp and their size. This works wonders if you are using rsync'ed
## servers, where the inode number of identical files differs.
## Note: It may cause problems on your server and you may need to remove it
FileETag MTime Size
########## End - ETag Optimization



#####################################################
# Beginning of additional settings by jawsmith (from the
# "htaccess.txt" provided with Joomla, and Joomla
# security forums)
#####################################################
# Code taken from "Other useful settings" of http://docs.joomla.org/Htaccess_examples_(security)
ServerSignature Off

# Disable all methods except GET and POST, as only those are needed
# (Note: TRACE does not seem to be possible to disable in .htaccess, only in server config by the host)
RewriteCond %{REQUEST_METHOD} !^(GET|POST) [NC]
# Return 405 Method Not Allowed
RewriteRule .* - [R=405,L]

RewriteCond %{THE_REQUEST} (\\r|\\n|%0A|%0D) [NC,OR]
RewriteCond %{HTTP_REFERER} (<|>|’|%0A|%0D|%27|%3C|%3E|%00) [NC,OR]
RewriteCond %{HTTP_COOKIE} (<|>|’|%0A|%0D|%27|%3C|%3E|%00) [NC,OR]
RewriteCond %{REQUEST_URI} ^/(,|;|:|<|>|”>|”<|/|\\\.\.\\).{0,9999} [NC,OR]

# Note: User agents blocking not taken over, as agent names could easily be changed, and e.g. Nikto is used by me as well on http://www.hackertarget.com/website-scan

#Block mySQL injects
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} \.\./\.\. [OR]
RewriteCond %{QUERY_STRING} (localhost|loopback|127\.0\.0\.1) [NC,OR]
# Comment by jawsmith: commented following out, as otherwise error by the world map widget (flash)
#RewriteCond %{QUERY_STRING} \.[a-z0-9] [NC,OR]
RewriteCond %{QUERY_STRING} (<|>|’|%0A|%0D|%27|%3C|%3E|%00) [NC]
# Note: The final RewriteCond must NOT use the [OR] flag.

# Return 403 Forbidden
RewriteRule .* - [F]

########## Begin - Rewrite rules to block out some common exploits
## If you experience problems on your site block out the operations listed below
## This attempts to block the most common type of exploit `attempts` to Joomla!

# Protect .htaccess (Note: other file extensions will be
# protected implicitly by rewrite rules (folder access, etc.) below.)
<FilesMatch "\.htaccess$">
Order allow,deny
Deny from all
</FilesMatch>
#####################################################
# End of additional settings by jawsmith
#####################################################



########## Begin - Rewrite rules to block out some common exploits
## If you experience problems on your site block out the operations listed below
## This attempts to block the most common type of exploit `attempts` to Joomla!
#
# If the request query string contains /proc/self/environ (by SigSiu.net)
RewriteCond %{QUERY_STRING} proc/self/environ [OR]
# Block out any script trying to set a mosConfig value through the URL
# (these attacks wouldn't work w/out Joomla! 1.5's Legacy Mode plugin)
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
# Block out any script trying to base64_encode or base64_decode data within the 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})
# Return 403 Forbidden
RewriteRule .* - [F]
#
########## End - Rewrite rules to block out some common exploits

########## Begin - File injection protection, by SigSiu.net
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=http:// [OR]
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=(\.\.//?)+ [OR]
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=/([a-z0-9_.]//?)+ [NC]
RewriteRule .* - [F]
########## End - File injection protection

########## Begin - Advanced server protection - query strings, referrer and config
# Advanced server protection, version 3.2 - May 2011
# by Nicholas K. Dionysopoulos

## Disallow PHP Easter Eggs (can be used in fingerprinting attacks to determine
## your PHP version). See http://www.0php.com/php_easter_egg.php and
## http://osvdb.org/12184 for more information
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]
RewriteRule .* - [F]

## SQLi first line of defense, thanks to Radek Suski (SigSiu.net) @
## http://www.sigsiu.net/presentations/fortifying_your_joomla_website.html
## May cause problems on legitimate requests
RewriteCond %{QUERY_STRING} concat[^\(]*\( [NC,OR]
RewriteCond %{QUERY_STRING} union([^s]*s)+elect [NC,OR]
RewriteCond %{QUERY_STRING} union([^a]*a)+ll([^s]*s)+elect [NC]
RewriteRule .* - [F]

########## End - Advanced server protection - query strings, referrer and config

########################################################################
# Added by jawsmith: sub-domain prevention and www requirement (redirect with code 301 ("moved permanently")
# in the same rule
# Notes: 1. If you want to do it separately, or use https, refer to Joomla reference htaccess implementation
#        2. This needs to be done before the below file protection exceptions,
#           so that the redirect occurs before the exceptions are accessed. And no F or L flag,
#           so that execution proceeds.
#        3. Replace test.example.com with your own domain
########################################################################
RewriteCond %{HTTP_HOST} !^www\.test\.example\.com$
RewriteRule ^(.*)$ http://www.test.example.com/$1 [R=301]

########## Begin - Advanced server protection rules exceptions ####
##
## These are sample exceptions to the Advanced Server Protection 3.1
## rule set further down this file.
##
## Allow Piwik API files
RewriteRule ^piwik/(index\.php|piwik\.(php|js))$ - [L]
RewriteRule ^piwik/js/(index\.php|piwik\.js)$ - [L]

########## End - Advanced server protection rules exceptions ####

########## Begin - Advanced server protection - paths and files
# Advanced server protection, version 3.2 - May 2011
# by Nicholas K. Dionysopoulos

## Disallow front-end access for certain Piwik system directories
# (Note: "js" directory deliberately not disallowed, as contains scripts accessible by browser)
RewriteRule ^piwik/(config|core|lang|misc|tests|tmp)/ - [F]

## Allow limited access for certain Piwik system directories with client-accessible content
RewriteRule ^piwik/(libs|plugins|themes)/([^/]+/)*([^/.]+\.)+(jp(e?g|2)?|png|gif|bmp|css|js|swf|html?|pdf|svg|ico)$ - [L]
RewriteRule ^piwik/(libs|plugins|themes)/ - [F]

## Disallow access to rogue PHP files throughout the site, unless they are explicitly allowed
# (Note: This is not needed, as no SEO is used - all access through files excepted above, and no SEO pseudo directories are used)
#RewriteCond %{REQUEST_FILENAME} \.php$
#RewriteCond %{REQUEST_FILENAME} !/(index|piwik)\.php$
#RewriteCond %{REQUEST_FILENAME} -f
#RewriteRule ^([^/]+/)*([^/.]+\.)+php$ - [F]

########## End - Advanced server protection - paths and files

As an additional tweak, following files were removed from the Piwik installation, to limit “fingerprinting”, and to prevent the need in the above .htaccess to disable access to them if they were kept:
\piwik\LEGALNOTICE
\piwik\README
\piwik\js\LICENSE.txt
\piwik\js\README

Note that those are in the only directories accessible by the client - the Piwik installation directory and the “js” directory. Access to other similar files will be implicitly prevented by the above .htaccess file - via directory access prevention.

Additional hint: As with any other web application, unless you use https AND your TLS is super up-to-date AND your client is up-to-date and secure, try to log-in to your Piwik installation with administrator rights as little as possible. Simply create an additional account restricted to “viewing” and use it when no administration work is required. And: same applies if the above “unless” condition is met, as we all know that a piece of software stays secure forever. :wink: