I have a situation where I want to protect a file from public access, but enable read and write from php. The file contains sensitive information like passwords.
The problem is that
I cannot put the file outside the web root (server security restriction on access from php)
I would like to avoid mysql database.
Also I would try to avoid .htacess files.
So if I make a folder, say private, in the web root, and do
chmod 700 private
Then, if the file to protect is private/data, I do
chmod 700 private/file
will this be a safe setup? So now I can read and write to the file from php but it is not accessible for the public?
Is this a safe setup?
PHP runs as the same user as the webserver so if PHP can read it, so can your webserver (and vice versa).
If you don't want to use .htaccess there is another trick: save the file as a .php file. Even if someone accesses the file from the web they can't see the source, they might just get a white page or maybe an error depending on what exactly is in the file.
If you're running suPHP or fastCGI php, you can use a setup similar to what you've described to limit access to files. Otherwise, PHP will use the same user as the web server, and any file PHP can access is also accessible via url.
If want to keep the restrictions stipulated (which are rather strange), and as (i guess) you do not wish/have access to apache config directives, consider adding PHP to some group and give the group only rights to the file, ie. apache cannot read (if its not in root/wheel).
Or make it a valid .php file (so only php would be invoker when the file is requested) which returns nothing or redirects when invoked with php. or just cipher it.
Related
Is it possible to arrange file permissions/group ownership/etc in such a way that a file can be read by the function readFile() for a forced download, but it cannot be downloaded by navigating to the literal url of the file?
Maybe you could add the user that is running apache / php to the group that owns the file. And set config to read and write for owner and owner group, and no permission at all for others. (-rwxrw---- 0r 0760)
Never tested it, but it should work.
The Apache user will need read permissions. To prevent it from being navigated to, the best (and easiest) solution is to store the file outside of the web folder.
Sorry if this is a trivial question.
I am a kind of new to PHP and I'm creating a project from scratch. I need to store my application logs (generated using log4php) as files, and I don't want them to be public.
They are now stored in a subfolder under my PHP application folder, (/myAppFolder/logs) so they are served by Apache.
Where shall I store them, or what shall I do to keep them away from being served as content by Apache?
You can either have them in a directory above the root, or, if you're on shared host/ can't have the files above the root for whatever reason, you can have them in a directory that denies all HTTP access.
So you could have a folder called "secret_files" with a .htaccess file sitting inside:
.htaccess:
deny from all
Which will prevent HTTP access to files/subfolders in that folder.
Somewhere not under the public root!?
This is more a server config question as it depends on your server, but in apache you could use the custom log directives to set the location, so if you have
/www/myapp
Create
/www/log
and put them there instead. You need control over the config to do this so look up your web hosts docs to find out how.
Is there a way to stop users from typing in a url and gaining access to a file in a specific directory but still allow a PHP script to have access to the file to change it or download it?
In other words, I want to stop people from typing in: http://www.mysite.com/securefolder/file1.pdf. Maybe redirect them to a different page or something.
But I do not want to completely lock away the files because I still need to use a PHP script to download and modify the files.
Any help is appreciated,
Thanks
If all you want is a specific setting for a certain file a very simple rule will be all you need -
RewriteEngine on
RewriteRule ^/securefolder/file1.pdf$ access_denied.php
What might be a better idea is to make a rule for the entire secured folder -
RewriteEngine on
RewriteRule ^/securefolder/.*$ access_denied.php
One last (and probably best) way to do this is to create an additional .htaccess inside the secured folder and simply deny all access to it. Place this one line -
deny from all
In all of the solutions, we are only talking about external requests. All your scripts and internal paths to scripts, files, etc... will remain intact and unaffected by the rules you define within the .htaccess files.
Disable direct access to the file on the webserver, and serve the file from a PHP script (some hints on this manual page: http://www.php.net/manual/en/function.readfile.php). Webserver access restictions won't affect PHP, as it is directly accessing the filesystem. Here's a similar question: Secure files for download
If performance is critical, there is plugin for most of the webservers which will help you to serve the file directly (bypassing PHP):
Apache mod_auth_token
Lighttpd mod_secdownload
Nginx secure_download
The ideal approach will depend on whether the PHP script accesses the PDF file locally on disk, or remotely over http.
If the PHP script accesses the file locally on disk, simply place the file outside the root folder of the web site.
If the PHP script access the file remotely over http, here are some options:
Limit access by origin IP
Password protect the resource and serve over https
If the files are on the same server, you don't need to download them in order to serve them. Simply read them from the filesystem and output them directly.
If, however, they're not, and you need a script to be able to download files, and others to be refused, you could password protect the directory.
To then download files using for instance cURL, you can specify the following options:
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
More information
Password Protecting Your Pages with htaccess
Sending a username and password with PHP cURL
Place your data file outside of the public web space. Read the file using PHP and serve.
There is no reason for the source file to be located within the web host's DocumentRoot unless you want the file to be served publicly.
A PHP script runs as local user and so is able to read the file even outside the scope of Apache (or other) web server.
I log sensitive information in a a log file lets call it "mylogfile.log". This file should in no circumstances be access from the outside/web.
I already protect it by using a .htaccess file but what i would like some extra safeguard like using a fileextension that is protected by the system. Is there any such?
The reason for the extra security is that this webapp is distrubuted to clients that could change or remove the .htaccess file. Also .htaccess override needs to be enabled in Apache.
You should put it outside of the document root.
If /var/www/your-site.com/public matches the URI your-site.com (public/index.html --> your-site.com/index.html etc), then log files will not be readable if you place them in /var/www/your-site.com/logs
When distributing an app like this, I would always make sure that you, given your limited and controlled space, do not use your "base folder" as the document root of the webserver, just to get some privacy around it.
I've got a "globabVars.php" doc in my own little framework that contains database connection vars etc... I'm thinking would be neat to store outside of the web facing directories to keep it a little more secure. But, then I was thinking, is it really THAT much more secure? I mean, if someone were able to look at my .php files as a whole (without the server processing them) they would be INSIDE my server looking at all my files anyway...
Thoughts?
Moving a config file outside of the web root can prevent this file from getting leaked if you accidentally mis-configure apache. For instance if you remove Apache's mod_php then all .php files will be treated as text files. I have seen config files moved outside of the web root on production systems for this reason, and it did stop the file from getting leaked! (An admin iced the config during an update, doah!). Although this doesn't happen very often.
If an attacker can control the path of one of these functions: file_get_contents(), fopen(), readfile() or fgets() then he can read any file on your system. You also have to worry about sql injection. For instance this query under MySQL can be used to read files: select load_file("/etc/passwd").
To mitigate this issue, remove FILE privileges from your MySQL user account that PHP uses. Also do a chmod 500 -R /path/to/web/root, The last 2 zeros keeps any other account from accessing the files. You should also follow it up with a chown www-data -R /path/to/web/root where www-data is the user account that php is executed as, you can figure this out by doing a <?php system('whoami');?>.
It means noone can access it via a URL by default.
You can hide with .htaccess if it is in your docroot, but storing it above the docroot is just that bit safer.
You can have it read via PHP if your application is prone to directory traversal attacks.
Yeah, you are right. There is a very small difference.