If a site has php session's in place to enforce authentication/authorization to pages on the site which are implemented in php, how does the same logic enforce access to certain files.
Lets say a repository of files in a directory. So /var/www/html/ is protected via authentication however, this PHP authentication logic won't prohibit a user from simply going to http://site.com/someDirectory/fileIShouldNotAccess.txt and pulling that file.
How do you couple the php session and authentication with apache to enforce this type of behavior?
Since PHP won't be invoked when the user requests a non-PHP file, you can't have Apache enforce PHP's access protection. You can make a very coarse and easy-to-fake check in Apache to make sure that a session ID cookie is present, but that's highly insecure. It just checks if the cookie's there, not that it represents a valid session or that the user's actually been granted access.
This other answer might help. Using PHP/Apache to restrict access to static files (html, css, img, etc). Basically, you serve up all the protected content via a PHP script, instead of providing direct access.
A couple answers:
1) make your php sessions use HTTP authentication. Then you can use a .htaccess file to control file access in directories
2) Use mod_rewrite to redirect all requests to a "front controller". Let the front controller manage whether access is allowed, denied, or forwarded to a different controller module for further processing.
You can try HTTP Authentication with PHP. This article might help.
Related
I'd like to have logged in users access to certain directories only. For example, have the following directory structure:
/stuff/user-a/pic.jpg
/stuff/user-b/file.doc
I'd like Apache to only give user-a access to /stuff/user-a and give a 403 if he tries to reach /stuff/user-b
Now, I've been reading and it seems to be possible to do this with REMOTE_USER and mod_rewrite. Which will make it even better, as i could rewrite it as /stuff -> /stuff/$REMOTE_USER
The problem is, I don't want the ugly browser popup. My PHP application already has a login form and a session. From what I've been reading, it is possible to use basic HTTP authentication as an auth method for PHP (to login as http://user:pass#stackoverflow.com). But the opposite (passing a web form to the HTTP authentication) doesn't seem to be possible.
I would also like to avoid using something as mod_xsendfile, as I'd rather not use any "proxy" scripts to handle this, and let Apache take care of access.
Background
I'm looking for a transparent, PHP-driven authentication layer for a web site.
I'm aware of the following simple approaches:
HTTP Authentication
Mechanics:
Apache controls access rights;
Attempts to access any file in a given directory transparently require HTTP auth if not already authed.
Downsides:
Limited configuration options;
Difficult to integrate with existing user database;
No control over visual presentation of login prompt.
PHP-based login
Mechanics:
PHP controls access rights;
Attempts to access any file explicitly built for the system if not already authed will result in redirection to a login page.
Downsides:
If I forget to write the required include "login_required.inc.php"; or similar at the top of any PHP file, that file will be accessible by anybody.
What I want
I'd like to implement the PHP-based login solution, but to somehow configure Apache to invoke login_required.inc.php (or similar) transparently as an intermediate step when any PHP file is requested.
This script will:
run;
check session variables;
tell Apache either "yes, produce the requested page" or "no, redirect to the login page";
not require code to be inserted at the top of every PHP script that requires authentication.
Is this a pipe dream? Or can I do it? And if so, how?
If you rewrite all php requests through index.php, index.php/php would then control access to anything.
RewriteRule ^(.*)$ /index.php?pageid=$1 [QSA,L]
Something like that will push any request to index.php, in which you can do your authentication and then it will farm out the content...
The QSA in this will retain any query string parameters etc.
I think you should restructure you website to use a Front Controller. There's a reason that pretty much every framework uses the FrontController pattern: single point of access makes your app simpler.
One possibility is to use .htaccess ModRewrite to redirect all requests to, say, login_required.php?redirect=<ORIGINALLY-REQUESTED-SCRIPT>.
login_required.php can then perform its magic and do one of the following:
Present a login form
include <ORIGINALLY-REQUESTED-SCRIPT>.
Note that a header("Location: <ORIGINALLY-REQUESTED-SCRIPT>)"; will, I believe, merely fall foul of the .htaccess again and cause an infinite redirect loop! Setting the .htaccess ModRewrite directive to only conditionally redirect based on the value of HTTP_REFERER is not secure enough.
This is not the preferred solution, but it's a possibility...
Another possibility:
Have only a single entry-point. Just one file that's accessible from the outside world, like index.php?target=<REQUESTED-SCRIPT>. This one file can contain the authentication logic and include the required script.
All other files would be blocked from external access by .htaccess, or simple file permissions.
This is a good solution, but it would be a large change to update all URLs throughout the existing system.
Edit Apparently this is called the "Front Controller" pattern.
There is this PHP script on my website which I don't want people to be able to run by just typing its name in the browser.
Ideally I would like this script to be run only by registered users and only from within a Windows app (which I will have to provide). Can this be done ?
Alternatively, how can I protect this script so that it can only be called from a specific page or script?
Also how can I hide the exact URI from appearing on the address bar?
Thanks !
If you are running Apache for your webserver, you can protect it with a username/password combo using .htaccess. It takes a little configuration if your server is not already configured to allow .htaccess. Here are the Apache docs.
If you need authentication based on application-specific factors, you can put something at the top of your script like
<?php
if(!$user->isLoggedIn()) {
// do 404
header('HTTP/1.0 404 Not Found');
}
Do you have a question about how you would implement isLoggedIn?
You can also use mod_rewrite to rewrite URIs, and those directives can go inside your .htaccess as well. mod_rewrite can rewrite incoming requests transparently (from the browser's perspective) so a request for /foo/bar can be translated into secret_script.php/foo/bar. Docs for mod_rewrite.
However you decide to implement this, I would urge you to not rely solely on the fact that your script's name is obscure as a means to secure your application. At the very least, use .htaccess with some per-user authentication, and consider having your application authenticate users as well.
As Jesse says, it's possible to restrict your script to logged in users. There are a large number of questions on this already. Search for PHP authentication.
However, it is not possible to restrict it to a single application. It is fairly simple to use a program like Wireshark to see exactly how the program logs in and makes request. At that point, they can reproduce its behavior manually or in their own application.
There are a variety of different ways that you could go about securing a script. All have pluses and minuses, and its likely that the correct answer for your situation will be a combination of several.
Like mentioned, you could lock down the account with Apache...it's a good start. Similarly, you could build a powerful 'salt-ed' security system such as this: http://www.devarticles.com/c/a/JavaScript/Building-a-CHAP-Login-System-An-ObjectOriented-Approach/ If you use SSL as well, you're essentially getting yourself security like banks use on their websites--not perfect, but certainly not easy to break into.
But there are other ideas to consider too. Park your script in a class file that sits inaccessible via direct URI, then do calls to the various functions from an intermediary view script. Not perfect, but it does limit the ways that someone could directly access the file. Consider adding a "qualifier" to the URL via a simple get--have the script check for the qualifier or fail....again, not a great solution on its own, but one additional layer to dissuade the bad guys. If you have control of who's getting access (know exactly which networks) you could even go so far as to limit the IP's or the http referers that are allowed to access the file. Consider setting and checking cookies, with a clear expiration. Don't forget to set your robots file so the browsers don't stumble upon the script your trying to protect.
A while back my company did a membership app using Delphi on the front end, talking to php and MySql on the backend....it was a bit clunky given that we were all web application developers. If you're so inclined, perhaps Adobe Flex might be an option. But ultimately, you'll have to open a door that the application could talk to, and if someone was determined, theoretically they could dig through your app to find the credentials and use them to gain instant access to the site. If you're going the desktop app route, perhaps its time to consider having the app avoid talking to an intermediary script and do its work on the local machine, communicating the db that sits remote.
you can use deny access on .htaccess on a folder with a php authentification that will redirect to those php file
Using php I authenticate a user, then behind the scenes,they are then again authenticated a second time with a single .htaccess username & password. This would be the same for all users, but I would not want them to have to enter a username and password again and they would now be allowed to enter the password protected directory. I prefer not to use http://username#password:somedomain.com.
Any thoughts?
You should not do this.
Either:
Add code to your .htaccess protected directory to use your PHP authentication scheme and remove the .htaccess authentication.
Write a new PHP page/script through which your authenticated users will access all of the protected content. Move the protected content out of the web root, or use your .htaccess file to deny all access. Your script will be able to access the files, but users will have to go through the script to access them.
If you want to avoid multiple logins but need HTTP authentication, you can use only HTTP authentication for the actual login. This is because PHP can issue and respond to such headers.
http://php.net/manual/en/features.http-auth.php
This way the user receives a pop up, PHP can read it and respond accordingly and the browser will pass it with subsequent requests eliminating further prompts.
Note: This solution is not available to CGI versions of PHP.
Sorry, I do not believe this is possible (unless you want to use the username:pass#url scheme). You could write some ajax to do it behind the scenes, which would mean that the browser will remember the auth for that area (maybe, I have never actually tried it). But you would still need the username/pass regardless.
For the security of not transmitting the password in clear text on the browser (I assume you are using https to transmit the password over the network, or if your not you should!) I think it will be a little annoying for the user, but not a huge amount of hassle in my opinion.
Of course you could do the authenticating on that other folder in PHP, which would solve the issue, or put all your protected code in the one place with the one HTTP auth, but I assume you dont want (or cant) do this.
.htaccess files are not my strong point.
I have document uploads going to /uploads. The user should be able to view the documents they've just uploaded by clicking on the document link that appears via ajax after uploading is completed.
However, I would like to be able to password protect the /uploads folder BUT still enable the current user to view the clicked document without having a password request appear.
Is this possible to do in .htaccess?
Thanks for any suggestions.
Unless you are using HTTP auth to authenticate your user before the upload, this probably cannot be simply done with just .htaccess. You need to know file's owner and compare it with current user, which is way beyond the scope of usual web server's capabilities.
If you may use Nginx or Lighttpd, you may use X-Accel-Redirect/X-Sendfile header. There's also a module for Apache2 called mod_xsendfile. Make all request to /uploads transparently pass through your application, verify access then tell web server to send file. While this requires the ability to configure the web server (which is sometimes not possible) this is probably the most correct and universal solution.
Here are some useful links:
PHP and Ruby on Rails examples (and some general information on configuration)
Python/Django code snippet
You could use cookie based authentication (mod_auth_cookie) to grant access via htaccess for a particular location.
I am not sure if setting the cookie path to the specific file will work, but its worth a try.
You are better off doing this in the app layer though.
EDIT: This may be a better solution
I don't think this is possible in .htaccess - since .htaccess has no way of knowing which user uploaded which files. Even if it did (e.g. by putting files in uploads/username/), I don't think .htaccess files are the way to go. I think you'll probably want to enforce this at the application level.