Here's the layout:
web root
- admin (dir)
- index.php
- js
- img
- other files / dirs
- dir
- files
Until now, I protected the admin dir with .htaccess passwd because I want full access control for all files in that dir (including js scripts, jpg, pdf etc). On the other hand, my custom CMS provides authentication using PHP sesssion / cookie for other URLs. What I want to accomplish is to use the same PHP authentication for the .htaccess protected dir, avoiding the popup prompt for user / password for already PHP authenticated users. In summary:
I want the admin dir to use the .htaccess rules for authentication
If a user is already authenticated using PHP (login in a HTML form, on a non-protected file), bypass the second .htaccess authentication process when accessing the admin dir content
If a non PHP authenticated user tries to access content in the admin dir, the HTTP auth popup should be triggered
Most of the stuff that I've read suggest to move the admin dir outside the web root and access the files from a PHP script with readfile, which I don't want to do. There's dynamic content on that dir, as well as static. I know that apache will trigger the auth popup before loading any resources so the question is how to make apache aware that the user is already authenticated. Any other suggestion / workaround?
You can use the SetEnvIf variable in the .htaccess file to check if a certain Cookie value is set. For example (this isn't very secure, but just for illustration):
AuthType Basic
AuthName "Protected Login"
AuthUserFile "/path/to/.htpasswd"
AuthGroupFile "/dev/null"
SetEnvIf Cookie PHPSESSID=.* PASS=1
Order deny,allow
Deny from all
Allow from env=PASS
Require valid-user
Satisfy any
The line SetEnvIf Cookie PHPSESSID=.* PASS=1 checks if a Cookie is set with a PHP session id and if so, that is enough to Satisfy the authentication process and the Allow from env=PASS makes it skip the login prompt if this is true.
Again, this example is not very safe as a PHP session cookie is already set when session_start() is called without a succesful authentication attempt, so it would be better to set a more cryptical/random cookie value that's hard to guess. For example:
SetEnvIf Cookie AJNC3Z921dmc4O8P2 PASS=1
That way, if you set a cookie value of AJNC3Z921dmc4O8P2 upon succesful authentication through PHP, this will be enough to pass the authentication process. Make sure to set a proper cookie expiration time though to avoid people from being able to pass the login prompt for a prolonged period.
Related
User login to the site and and with the appropriate permissions it allows to access to page policies/editor.php,from this page he has a link to access to directory: /home/account/app/Ui/policies/gray_list.
The good: the application manages internally the session, and once the user logout or session timeout expires, the user is directed to login page.
The bad, In case the user opened a tab to the directory, i.e. policies/gray_list/, he can stay there beyond that expiration, so even if the user logout from the site, he still can navigate to the directory.
How can I make the session expire (I assume using apache configuration)? So actually, what I want is that once the session timeout the user will at least get the forbidden 403 error, like he currently gets when he tries to access this folder directly and not from policies/editor.php
My current configuration:
SetEnvIf Referer "policies/editor.php" editorpage
SetEnvIf Referer "policies/gray_list/" graylistfolder
<Directory "/home/account/app/Ui/policies/gray_list">
Options Indexes FollowSymLinks
IndexIgnore ..
Order Deny,Allow
Deny from all
Allow from env=editorpage
Allow from env=graylistfolder
</Directory>
How exactly is your session implemented? If we are talking about PHP sessions here – there is no “simple” connection between those and Apache default functionality.
In that case, then you’re better of disabling directory content listing via Apache, and use a PHP script to read the directory contents and present it to the user (either by making a PHP script the DirectoryIndex file, or by rewriting directory requests to the script) – that way, you can handle your session resp its expiry accordingly.
And relying on the referer is of course no real “protection” at all, since that value is optional as well as most easily fake-able.
I have been toying with http authentication using the .htaccess file in an attempt to better my current cms.
I have found a solution in apache whereas, I use a link in my html somewhere Test.
I then add this to my .htaccess:
<Files .test>
AuthType Digest
AuthNAme "Restricted Page"
AuthDigestProvider file
AuthUserFile /usr/home/myDomain/includes/htpasswd/admin/.htdigest
Require valid-user
# If user is authenticated then redirect
RewriteEngine on
RewriteCond %{REMOTE_USER} !=""
RewriteRule ^.*$ /test.php? [R]
</Files>
What this does, is when a user clicks on the mentioned hyperlink, the user is then prompted with a login form via http authentication. When they enter the correct credentials, they are redirected to a page in the accessable root called test.php, which in turn includes the cms index that is held out of the web root.
If a user selects a section within the cms, they are prompted to log in again (using the sites default php based log in system) and only users with the correct role assignments may access any specfic section.
Although this is useful, it is not quite what i am trying to accomplish.
What i have thought of, is two possible solutions in my case.
One would be where a user could enter say http://www.myDomain.com/?whateveryoulike in the address and be directed to my cms instead. Ideally this redirection would direct straight to my cms index in its' root directory that is not accessable via http://. Something like this which can be done in php:
if isset($_GET['whateveryoulike'])
{
include $_SERVER['DOCUMENT_ROOT'] . '/../../admin/blah.php';
}
Another option i thought of would be something i do not know very much about, but it relates to http authentication and i have seen in use once before...
Basically the user enters username#www.myDomain.com and they get prompted with the http auth log in box. When the credentials are met, they are sent to a seperate section within the website.
Would anyone be able to provide any input, suggestions or addittional ideas relating to how i would go about this?
My question though, is if it is possible to actually catch a GET (http://www.myDomain.com/?whateveryoulike) apply http authentication then redirect the user to a page that is held out of the http:// root?
Thank you for taking the time to read through this!
it is possible to actually catch a GET, apply http authentication then redirect the user to a page that is held out of the http:// root?
No.
The reason is possible fraud, which was used some years ago.
Since then browsers refuse to authorize users silently.
I see no point in the whole enterprize at all, though.
i want to deny access (from all non-logged in users) to all the files in a directory from the browser.
Only a logged in user can access his files in that folder. The file paths are stored in the database with the logged in user id, so that when the user logs in, he can view or download only his files.
So i dont want others (without logging in) to access the folder and files from the browser, and secondly, i want the users to be able to view only their files in the folder.
I think, Second thing i can do with some condition checks in php, but for the first one, can anyone tell me the htaccess rule to achieve ?
Thank you
dont show them the actual folder path where their files are stored.
Use a php file to fetch the downloadable content.
eg :- download.php?file=mydocument.doc
Cons :
Might be slow
No Download Resume support (I guess)
For the part of .htaccess user access you can take a look here at the .htaccess Password Generator
You can disable default directory browsing using .htaccess.
Open your .htacces file
Look for Options Indexes
If Options Indexes exists modify it
to Options -Indexes or else add
Options -Indexes as a new line
The directory browsing feature should be disable by now
There's article, which describes access control feature of Apache web server thoroughly: http://httpd.apache.org/docs/2.0/howto/auth.html
The easiest variant looks in the following way:
AuthType Basic
AuthName "Restricted Files"
AuthUserFile /usr/local/apache/passwd/passwords
BTW, this part:
Only a logged in user can access his
files in that folder. The file paths
are stored in the database with the
logged in user id, so that when the
user logs in, he can view or download
only his files.
will require either creation of separate password files for each folder, or some additional scripting.
There are some known issues with this approach:
Basic authentication scheme sends passwords as a clear text, which is not good if your site is accessible by HTTP (not HTTPS). There's also Digest authentication type, but there were some problems with browser support
Logout operation will require browser closing
Generally, I'd recommend:
Apache built-in capabilities - for simple access control without detailed users privileges/rights configuration
Custom access control by means of some web programming tools - for authentication scheme with supposed priveleges/rights configuration. There are many web development frameworks, which provide access control feature.
thanks for your replies, between i found a code snippet that is working just fine.
I inserted the following lines in my .htaccess file:
Order deny, allow
deny from all
what is the most secure way to password protect admin files/folders?
im on apache/php
The most secure way is to keep it off the internet alltogether ;-)
But irony aside, I'd suggest using .htaccess. Simple and requires no programming effort from you.
http://www.htpasswdgenerator.com/apache/htaccess.html#8
An alternative to the htaccess method is to put the files that should be protected outside the web-root - somewhere where a typical HTTP request can't reach them - and have PHP relay them back to the client as needed.
This is useful in situations where you need more control over the process than Apache gives you. Like, say: if you wanted to integrate this with your PHP application's member functionality; allowing members that have already logged in access to the files while denying access to others.
Create a .htaccess and .htpasswd with one of the 10000 .htaccess generators out there and use the htpasswd included in most distros to add users to the .htpasswd.
Securing admin folder with HTTP Authentication (.htpasswd & .htaccess)
Navigate to http://aspirine.org/htpasswd_en.html to generate
username and password in an encrypted form
Eg:
username: User_name
password: Mypassword
Result will be depending upon your selected hashing algorithm
Eg.:
User_name:TX9D66ksKUR0o
Save this in “.htpasswd” file
Creating a “.htpasswd” file on your web server other than the /public_html
directory. Preferably one directory above it in the /home folder which would
store the username and password in an encrypted form for the HTTP
authentication.
Add the following code to the .htaccess file inside the /admin
folder on your server. Do not forget to put the correct path of the
.htpasswd file in the following code snippet:
AuthType Basic
AuthName "Your_Name"
AuthUserFile path-to/.htpasswd/file
Require valid-user
AuthName "Authorisation Required"
require valid-user
# IP
# order deny,allow
# deny from all
# allow from xxx.xx.xx.xxx
I have a structure like this:
/home
/home/dir1
/home/dir2
Now when someone goes to /home, he is asked for username and password (in a form) and I set session information in PHP for the remaining files of /home. Now /home/dir1 and /home/dir2 are protected by htpasswd but the same username and password. I dont want the user to re-enter their username and password again when they go to /home/dir1... Also when I logout from /home, I want to logout from /home/dir1 also. Can you please advice on how to achieve this?
This should be the default behaviour.
That is, if you are using Apache and .htaccess files to set up HTTP authentication, any rules you apply to a directory will also apply to its child directories, and it will be treated by the browser as all one login.
If you want it to act differently, ie if you wanted some sections of the site to be treated as requiring a completely separate login, you would specify a 'realm' for each section using the AuthName directive in .htaccess. More information here. However, if you don't do that, it will always be treated as all part of the same login.
The thing about HTTP authentication is that there is no way to 'log out', at least not unless the browser provides that feature. The only way most browsers will allow you to log you out is by ending the browser session (ie closing the browser). And yes, once you do this, you'll be logged out of /home, /home/dir1, /home/dir2 and all directories on all sites/realms.
In Apache as long as both folders have the same AuthName and are on the same site they should share a password.
Both directories might have a .htaccess file like so:
AuthName "My Protect Folder"
AuthType basic
AuthUserFile /somewhere/htusers
require valid-user