I have found in my server, that some files are stored inside the webroot, for example
example.com/files/longnamewithcode_1234293182391823212313231230812.pdf
They are stored for a web app and hace sensible info on them.
If you access example.com/files you get an empty index.html, so you can't directly scan the directory. Anyway, I'm concerned about this: I feel that it is not safe and I would like to know what kind of attacks could be made to access the files. I understand that some brute force attack would be possible, but with the long code names I guess it's a less big problem.
Finally, I would say that the correct way is storing the files outside the web folder and return them with PHP, but I'm not sure I'll be able to have access to the code to change this.
If you have to make the files accessible from webroot by the webserver you can't really make it more safe than use sufficient amount of entropy in the file names, but that still not account for simply sharing a the links by users that get a hold of them somehow.
If you want to implement the permission checking inside php take a look into the various X-Sendfile implementations on popular webservers like, mod_xsendfile (apache), XSendfile (nginx) or X-LIGHTTPD-send-file (lighttpd). This allows you to use the webserver to serve the file basically as efficiently as simply accessing it from the webroot after you validated the accessing user.
have you considered an .htaccess file to restrict who is allowed to access those sensible files? you tagged it, but i'm not sure why you are not using it. =)
If you wish to block everything in the folder you can use an .htaccess file to block all connections.
Try
deny from all
in the .htaccess file in that directory. This will deny all access to anything in that directory including the index file.
The question is
Are the files supposed to be accessed by users freely?
If yes, don't worry about those files too much (as long as they're not writeable).
If no, i.e. users have to be logged in to download them, move them out from the publicly accessible folder and deeper into the application. Write a php script that will manage the permissions for the file i.e. /download?file_id=1.
Related
I have a folder called data which has .ini files that my scripts access. I've put a .htaccess in the data folder with deny all so that the folder cannot be accessed directly. This way only my scripts on the server can access it.
Is this .htaccess method good enough? i've also tested chmod the folder to 700 which seems to also do exactly the same thing, it denies public access but allows scripts to access the files.
I am wondering if I should just use both methods? or is one method better than the other?
Ideally, I assume it would be better to place the files outside the www folder but I do not have access to that.
The .htaccess solution will stop requests from a client from reading the files via a web browser or similar:
deny from all
The advantage of the .htaccess file is that a future developer or admin would see the file and know you had deliberately chosen to protect that code in a well recognised way. This could help avoid issues down the line. For example if the site was copied to a new server.
Is there any way to prevent a user from writing code to include a php file if they have access to the server? I can't use a .htaccess deny from all type solution because as I understand it that is only for remote access. I also can't use a solution like the ones described here link from Tyler Carter because I process all pages from one central call which includes the appropriate page parts. Thus, $_SERVER['PHP_SELF'] always returns the same file, and I can't get the FILE of the calling script in the called script. So neither of those work.
I simply want to prevent the parts I include in the central file not to themselves call other files on the server outside their own directory.
I hope I am missing something and that this can be accomplished with .htaccess?
I guess a bigger question is if this is even a worthwhile security endeavor?
No.
If the user has the right to write files to your web-root, there is nothing you can do to prevent him/her from creating PHP files (short of writing your own FileSystem).
If you don't trust a user, they should not have the ability to write to your FS. This attack is actually quite commonly used in the real world against CMS installations. A user with file upload permissions uploads a PHP shell to take over the server.
I've been wondering: is it possible to shield a directory/file on a server from the outside world, but make it accessible to PHP?
It's fairly simple. I'm caching webpages on my server with PHP in a certain directory, but I do not want web users to view these files or this directory directly. PHP, on the other hand, must be able to access these files (to serve them to the user). That may sound not logical, but what I'm trying to do is restrict users certain pages and still be able to cache them in a webserver-savvy format.
Preferably something with .htaccess or chmod.
Thanks!
Absolutely-- in fact, you don't need to use .htaccess. Simply put the protected directory above your document root (that is, store it next to the folder where your PHP scripts are store, typically "htdocs," "httpdocs" or sometimes just "www').
So your web files would be in /my/folders/httpdocs/, and your "protected" files would be in /my/folders/protected_folder/
The idea here is that PHP can access any folder on the server, but Apache won't let the user navigate "above" the root directory.
To access the directory, you can use:
$protected_path = $_SERVER['DOCUMENT_ROOT'].'/../protected_folder/';
(Incidentally, you mentioned you're doing this to cache pages-- you might want to look at Smarty, the PHP template engine, which pre-compiles your templates and also supports really smart caching. And in fact, one of the Smarty "best practices" is to configure your structure so the template and cache files are not in or below the document_root folder, so users coming in from Apache can never get to them, but the Smarty PHP code can easily grab whatever it needs from there.)
Sure, just place the files in a directory outside of your web root. For instance, if your web root is /usr/local/apache/htdocs/ you can create a /usr/local/apache/private_cache/ directory that PHP should have access to, but there is no way to get to it via a web request.
You can also put a .htaccess file consisting of the line deny from all in the directory you want to protect. That will prevent Apache (but not PHP) from serving up the files.
Is it possible to "deny from all" apache htaccess style using php.
I can't use htaccess because im using different webserver, so i wan't to use php to workaround it.
So let say user are trying to access folder name 'david', all content and subdirectory are denied from viewing.
No
PHP cannot be used to protect folders.
Because it is not PHP who serves requests, but a web server
You can move this catalog above Document Root to prevent web access to it.
But premissions will help you nothing
Use chmod to change the permissions on that directory. Note that the user running PHP needs to own it in that case.
If you just want to prevent indexing the folder, you can create an index.php file that does a simple redirection. Note: Requests that have a valid filename will still be let through.
<?php
header("Location: /"); // redirect user to root directory
Without cooperation from the webserver the only way to protect your files is
to encrypt them, in an archive, maybe, of which your script would know the password and tell no one - that will end up wasting cpu as the server will be decrypting it all the time, or
to use an incredibly deranged file naming scheme, a file naming scheme you won't ever describe to anyone, and that only your php script can sort trough.
Still data could be downloaded, bandwidth go to waste and encrypted files decrypted.
It all depends on how much that data matters. And how much your time costs, as these convoluted layers of somewhat penetrable obfuscation will likely eat huge chunks of developer time.
Now, as I said... that would be without cooperation from the webserver... but what if the webserver is cooperating and doesn't know?
I've seen some apache webservers, (can anyone confirm it's in the standard distribution?) for instance, come preloaded with a rule denying access to files starting with .ht, not only .htaccess but everything similar: .htproxy, .htcache, .htwhatever_comes_to_mind, .htyourmama...
Chances are your server could be one of those.
If that's the case... rename your hidden files .hthidden-<filename1>,.hthidden-<filename2>... and you'll get access to them only through php file functions, like readfile()
I it safe to place config.php in the root of your website even though it has premissions set to 644?
your config.php should be readable by your web serevr, and no fiddling with permissions will change that.
also, putting it anywhere else will not help much - because since your php code should be able to read it, any hacker that manage to run his code on your server will be able to read it.
so, no matter where you put it, it's in danger of being accessed by a hacker that managed to hack your server. putting it in the web root is not more or less secure than putting it anywhere else.
As long as no-one has an SSH or FTP access to your server, and that there is no bug / security hole in your website that would allow anyone to access the sources of the PHP files, this should be quite OK.
Note that your Apache user has to access that file (so it can be included from other PHP scripts) ; so, wherever you put it, if you have a security hole that allows PHP files to be read by users, it won't change a thing.
An idea might be to put that file outside of the document root, or inside a directory protected by an .htaccess file denying access from anyone -- at least, this way, if your server is not well-configured and displays source-code of PHP files, the content of that file would not be displayed (as it could not be access/served directly via HTTP).
This will not help in the case of a security hole that allows PHP file to display the content of other PHP files (I've seen that happen), but that would still be a first step.