Is password protecting a directory with .htaccess the best way to prevent its files from being seen by unauthorized users? Are there any alternatives to protecting a directory's content while still making it accessible to people that are authenticated to view it?
Also, couldn't someone try to bruteforce their way in, causing strain on the server?
Several things to notice:
Adding security in a .htaccess can always be done without the .htaccess, by using <Directory> instructions in the main configuration (or the virtualhost configuration). It will go faster (if you remove completly support for .htaccess with AllowOverride None) and you wont get the risk of someone altering your .htaccess.
There's several ways of adding security in .htaccess files, one of these ways is by using Basic HTTP Authentification with .htpasswd files. These .htpasswd files shouldn't be in the web directory root. One of the other possibility is using HTTP Digest Authentification, with the restriction that very old browsers won't support it (like IE6).
We usually encounter HTTP Basic Authentification. This is a very weak protection, simply because of the way it works. At the 1st request you're rejected, then your browser ask you for a password and login, and memorize this password login association for the webserver requested. Then for every request sent to this webserver until you close your browser the login and password will be added in the request header, unencrypted. There's simply a base64 encoding applied to the string 'Yourlogin:Yourpassword', to make it look like a pure ASCII7 strings and prevent encoding problems.
So anyone sniffing your request (wifi hotspot, man in the middle, local network, echo switch, etc) will know your password and login. Bad. The rule is ":
never ever use Basic HTTP
Authentification if the connection
isn't HTTPS (SSL).
If your webserver is completly in HTTPS no problem (see edit on the bottom), the clear text/password are encrypted by SSL.
For the brute force problem (and yes, some people can try to brute force the login/password, except if you tune a mod_security module to prevent that) the Security Consideration of the htpasswd page is quite clear:
When using the crypt() algorithm, note that only the first 8 characters of the password are used to form the password. If the supplied password is longer, the extra characters will be silently discarded
and:
On the Windows and MPE platforms, passwords encrypted with htpasswd are limited to no more than 255 characters in length. Longer passwords will be truncated to 255 characters.
So use SHA encoding hashing for passwords (even if it's not salted).
Another way to let authenticated user browse a directory content is to handle the directory listing and file upload within your application (PHP, Tomcat, etc) and not with the apache automatic listing. In term of security the automatic listing module (mod_autoindex) is something you shouldn't even have on your running apache.
Edit
Full HTTPS server is not required if you want to protect only some url with HTTP authentification. What you really need is that all these protected url should be in https, if non-protected url are in the http domain the authentification headers won't be used as this is a different domain (and the authentification headers are sent by domain). So you could add basic redirection rules in the http domain for these url, maybe something like that:
RedirectMatch 301 ^/secure/(.*)$ https://www.example.com/secure/$1
Related
I have site where user need to get http basic authentication prior to access the url lets say www.mybasicauthurl.com. Basic authentication can be passed in either way
Browse the url and enter the username, password on the pop-up if not done already.
Access the url as: username:password#www.mybasicauthurl.com
Now I use approach #2 supply the basic auth credential via url itself. This works fine and I can able to see the legitimate web page but
When I open firebug and see the all loaded static files it shows me something like
http://username:password#www.mybasicauthurl.com/static/jquery/jquery.js
http://username:password#www.mybasicauthurl.com/static/css/styles.css
http://username:password#www.mybasicauthurl.com/static/image/image1.png
Please note the prepend text username:password# in the url. I don't want that I just want these static files to be loaded normally like
http://www.mybasicauthurl.com/static/css/styles.css
I don't know if this is something done by the browser or apache server.
Would be appreciated even if share some useful link that I missed to google.
If you want to avoid HTTP auth on static resources, the best thing to do is to remove it server-side.
That means static resources would ba available without authentication, but if nothing important is present in the static resources, that's good.
Should be something like that:
# Apache < 2.4
<Location /static>
Satisfy Any
Allow from all
</Location>
# Apache >= 2.4
<Location /static>
Require all granted
</Location>
Another point. If the thing you do not like is the presence of username:password in the HTML source, that's effectively quite bad, and depending on the browsers versions it may or may not be supported (tends to be removed). That's a clear text information, could be intercepted or stored on the browser cache. But you are also using http:// and not https:// and this is even worse. The username:password is transmitted in clear text for each request of the browser, everybody can read this information!
When using Basic HTTP Authentification you must use HTTPS. Credentials are transmitted with a simple base64 encoding, it's just an ascii-7-trick encoding (like utf-8 is an encoding). So if you want to protect this username/password information you will also need HTTPS.
I want to implement https on only a selection of my web-pages. I have purchased my SSL certificates etc and got them working. Despite this, due to speed demands i cannot afford to place them on every single page.
Instead i want my server to serve up http or https depending on the page being viewed. An example where this has been done is ‘99designs’
The problem in slightly more detail:
When my visitors first visit my site they only have access to non-sensitive information and therefore i want them to be presented with simple http.
Then once they login they are granted access to more sensitive information, e.g. profile information for which HTTPS is used to deliver.
Despite being logged in, if the user goes back to a non-sensitive page such as the homepage then i want it delivered using HTTP.
One common solution seems to be using the .htaccess file. The problem is that my site is relatively large meaning that to use this would require me to write a rule for every page (several hundred) to determine whether it should be server up using http or https.
And then there is the problem of defining user generated content pages.
Please help,
Many thanks,
David
You've not mentioned anything about the architecture you are using. Assuming that the SSL termination is on the webserver, then you should set up separate virtual hosts with completely seperate and non-overlapping document trees, and for preference, use a path schema which does not overlap (to avoid little accidents).
Are there any known flaws with htaccess protected pages?
I know they are acceptable to brute force attacks as there is no limit to the amount of times someone can attempt to login. And if a user can uploaded and execute a file on the server, all bets are off...
Are there any other .htaccess flaws?
.htaccess is just a means of specifying Apache configuration directives on a per-directory basis. They allow numerous different kinds of password protection.
If you are talking about HTTP Basic Authentication then the username and password are sent in cleartext with every request and are subject to sniffing (assuming you aren't using SSL).
Aside from that, they are subject to the usual issues that any password based system suffers from.
Using HTTP Basic Authentication doesn't grant any additional ability for users to upload and execute files. If they can do that already, then they can still do that. If they couldn't, they can't.
The use of .htaccess is common and is fairly secure. However it makes you more susceptible to other attacks, such as remote file file disclosure vulnerabilities. For instance the follow code could be used to undermine .htaccess.
include("./path/to/languages/".$_GET['lang']);
An exploit would look like this:
http://127.0.0.1/LFI_Vuln.php?lang=../../../.htaccess
This will cause the contents of .htaccess to be displayed to the attacker.
I'm in a development environment and we're using basic .htaccess/.htpasswd authentication to keep lurkers out. But some of my AJAX calls are coming back with HTTP/401 authentication failed errors. Is it possible for me to allow access only to those specific URL's? I can't easily do it by popping a new .htaccess in a subfolder because CodeIgniter uses ReWrites.
It's not possible to allow access only to those specific URL's. Unfortunately, .htaccess and .htpasswd authentication operates on a directory level only. And you're exactly right about why just using a subdirectory won't work - b/c of CI rewrites, which happen AFTER Apache has transferred control to CodeIgniter's index.php front controller.
The easy option, if you're working on something that (1) is not likely to be hacked in the first place, and (2) can't reveal sensitive data even if it is, is to use security via obscurity. Don't have any links to your dev site, include a noindex directive for search engine crawlers, and go on your merry way. This also has the advantage that you can test versions of the site with your colleagues and friends by just telling them the URL to go to.
If you're more worried about security, then you're probably building an auth module for your website's users. In that case, for your dev environment, just call that auth module in the constructor for all of your controllers, and redirect to the login page if the user is not logged in.
Good luck!
I have a site that is password-protected using a .htaccess and .htpasswd file. I'd like for users to bypass the login prompt ONLY if they come from a certain domain. Can this be done by embedding the .htaccess credentials as parameters in the link somehow?
I do manage the domain I'd like to whitelist, so how can I pass GET parameters in the link that the .htaccess file will process?
You should rethink this as it is trivial to spoof the referring domain (or any information from the client).
You users can easily select to save their username / password if they wish to.
That would be highly insecure, the http referrer can be easily manipulated and your login bypassed.
If you own the other sites you can add some http header or GET var. If you don't, start thinking another solution for what you want to do.