Safely host PHP websites on Windows - php

I would like to host a few 3rd party PHP scripts on a Windows server (running in VMware), so I am looking for a way to limit all the users to accessing their own directories (and subdirectories) and prevent them from executing anything on the machine.
Port 25 is completely blocked and there is a very low limit on the number of external connections they are allowed to make.
There must be others that have come across this issue and any ideas, advice and tips are welcome.Thanks!

For PHP, there's the open_basedir restriction that is supposed to limit PHP script access to certain directories, and it usually does. However, it seems to be flawed. Article here - It's from 2008 though, so the shortcomings described there may have been already addressed in a recent release.
There's also the much hated safe mode that may have its place until PHP 6 comes along (it will be removed there.) be very careful with allowing scripts to execute outside binaries.
Suhosin adds additional security and restriction possibilities to PHP and is certainly a good idea to install. Its defaults may interfere with more complex apps, so be sure to look deeply into its config file. However, it looks like you have to recompile PHP to get it running on Windows. This is something I would really recommend looking into.
If you need something stronger and can use Linux, putting Apache in a chroot jail is something I came across a few days ago. It looks totally advanced, though.

Related

How to give a PHP file its own execution space, denying it access to any other files outside of its directory?

I have users upload PHP files to my server (I know this is a security risk, but it must be done).
I might have to execute the PHP scripts on the server.
So I was wondering, is there a way I can deny those PHP scripts access to any files and any directories outside of their current folder? This would make it secure enough for me to use.
Thanks.
Sigh... "but it must be done" - says whom?
Some options might exist: Looking at the comments on the documentation for the (now-removed) PHP Safe Mode, I found a link to suPHP which "is a tool for executing PHP scripts with the permissions of their owners". This would require local UNIX accounts for each user though - which I'm not sure is possible in your situation.
A real solution would need to go much deeper. I was once on a website that allowed you to compile and run applications in just about any language, as part of an exam. By compiling some "interesting" programs, I was able to determine that I was actually running in a QEMU VM "jail", and they were somehow funneling IO to/from the VM via my HTTP connection.
But the right answer is probably, of course, don't do it. With more information as to what exactly you're designing, we might be able to offer more sane alternatives.
You could set up a chrooted environment for these scripts to run in. Not absolutely waterproof, but a lot better than potentially giving access to your entire filesystem.
This article contains lots of info on how to get certain services running correctly inside your chrooted environment, it also contains a link to a best practices document concerning the correct usage of chroot.
Now, php also has a chroot command, it might be possible to tinker some kind of "sandbox" that's "good enough" for your purposes by using that function.
Anyways, although chroot can help tremendously to protect your system during the execution of foreign code you should remain very careful, and the basic rule is to provide as little services and facilities inside the chrooted environment as possible. In that context, the SO article pointed to by Emilio Gort contains a (very long) list of exploitable functions, probably most or all of these should be blocked by using the disable_functions setting in php.ini

Secure system calls with php for an online Code Checker

While I do know that system calls and security don't go hand in hand, there is a project for which I do need it. I'm writing a small code checker and I need to compile and execute the user submitted code to test against my test cases.
Basically I want to run the code in a sandbox, so that it can't touch any files outside of the temporary directory and any files that it creates can't be accessed by the outside world.
Recently I came across an exploit with with which the user could create a file say shell.php with the following contents.
<?php
echo system($_GET['x']);
?>
This gives the attacker a remote shell and since the owner of the file is apache, the attacker could basically move around my entire /var/www where mysql passwords were stored along with other configuration information.
While I am aware of threats like SQL Injections and have sanitized the user input before any operations that involve the DB, I have no idea as to how I can set up the sandbox. What are the techniques that I can use to disable system calls (right now I'm searching for the word 'system' in the user submitted code and not executing those snippets where it is found) and restrict the access to the files that the user submitted code creates.
As of now my code checker only works for C and I plan to add support for other languages like C++, Java, Ruby and Python after I can secure it. Also I'd like to learn more about this problem that I've encountered so pointers to a place where I could learn more about web security would also be appreciated.
My development machine is running Mac OS Lion and the deployment machine is a linux server so if a solution, that was cross platform would be most appreciated but one that dealt with just the linux machine would do too.
What you will probably want to do is set up a chroot to some random temp directory on your filesystem for the user running your scripts. Here is some reading on setting up a chroot, and some security to-know's.
I would suggest you also install a security module such as suExec or MPM-iTK for Apache. Then, within your Apache's VirtualHost (if you are not running a virtual host, do so!), assign a specific UserID to handle requests for this specific VirtualHost. This separates the request from the Apache default user, and adds a little security.
AssignUserID nonprivilegeduser nonprivilegeduser
Then, harden PHP a little by setting the following PHP options so the user cannot access files outside of the specific directories, and move your tmp_dir and session_save_path within this directory. This will prevent the users access outside of their base directory.
php_admin_value open_basedir /var/www/
php_admin_value upload_tmp_dir /var/www/tmp
php_admin_value session.save_path /var/www/tmp
Along with the lines of PHP, prevent access to specific functions and classes, and read up on PHP's security write-up.
Also, I would have you look into for that user, disabling access to sudo and su, to prevent a script from attempting to access root privileges. Learn more, here.
All in all, you said it nice and clear. There is no way to fully prevent a user from accessing your system if they have the will. The trick is to just make it as difficult as possible, and confusing as possible for them.
There is no way to make this work on a cross-platform basis, period. Sandboxing is inherently highly system-specific.
On Mac OS X, there is the Sandbox facility. It is poorly documented, but quite effective (Google Chrome relies heavily on it). Some enterprising souls have documented parts of it. However, it's only available on Mac OS X, so that probably rules it out.
On Linux, your options are considerably less developed. Some kernels support the seccomp mechanism to prevent processes from using any except a small "safe" set of system calls; however, not all do. Moreover, that "safe" subset doesn't include some calls that you are likely to need in code that hasn't been specifically written to run under seccomp -- for instance, mmap and sbrk are not permitted, so you can't allocate memory. Helper tools like seccomp-nurse may get you somewhere, though.
Here are the things I suggest doing.
1.
Disable system classes and functions in php.ini with
disable_functions="system,curl_init,fopen..."
disable_classes="DirectoryIterator,SplFileObject..."
2.
Run in a read only environment with no important data stored on it. In case anyone ever got into your server you don't want them to access anything. A good way to do this is buy an Amazon AWS EC2 and use a jailed user to run your server and PHP.
3.
Ask people to break it. The only way you can find flaws and loop holes that you are unaware of is to find them. If necessary, get a temporary server with a "test" application that replicates the same type of application your "production" environment will be.
Here are some helpful resources.
List of functions to disable. It can definitely be expanded upon but it's a good start.
Information on to avoid security issues.
The source and README in Viper-7's Codepad
I think what you are looking for is Mandatory Access Control. In Linux, it is available via SeLinux. Using it you can limit who can execute what command. In your case, you can limit the php user (Apache) to execute only limited commands like gcc etc. Also look into AppArmor
Also, look into runkit php virtual environment
You can try to run user submitted code in a container (docker) which are very light weight VMs. They start in less than a second.

Does Wamp Server differ from a normal internet hosting provider?

I am using wamp server to develop a website using php, mysql, PDO, html and css.
My wamp server is using PHP 5.3.5, MySQL 5.5.8 and Apache 2.2.17, I am also using InnoDB for transactions.
Considering that my internet hosting provider has at least these versions of php, mysql, apache, and supports InnoDB will the website I build act in the exact same way.
Is it possible to design a website in wamp and then expect several errors when going live? And if so how is this overcome?
Thanks.
As others note, there are many potential hiccups (but I view them as learning opportunities.) But I've done it this way for over five years and have yet to find a difference that wasn't easily overcome. Just stick to the middle of the road, use defaults as much as makes sense, and have fun. It's a great way to explore the platform.
There are many things that can go wrong, most of them having to do with how the web server and PHP are built and configured.
The simplest example is PHP's safe mode: there are many things that safe mode does not allow, and turning it off may not be an option if you are on a shared host. Another example is which extensions are enabled in PHP (your app may require one which the host does not have).
Of course this is all moot if you rent the whole server (or a VM), as in this case you will be able to do whatever you please.
For completeness, I have to mention that there might be platform-specific differences in behavior resulting from the same library (which PHP uses to provide some functionality) compiling into different behavior on different platforms (think platform sniffing in C with #ifdef). I have been bitten by this in the past, but the possibility is not large enough to worry about it beforehand.
A lot of the issues can be worked around by moving constants into config files, like Jon says. Some issues will be less in your control and harder to diagnose. For instance, the output buffer control may be configured differently outside the DocumentRoot you have access to. This can cause confusing problems when you try to write headers out when other content has already been sent out. Similar issues with the timeout numbers, etc.

WebServer for existing app

We have an existing windows desktop app written in C# 6 that uses an MDB MS access database for its storage. I need to write a web interface that can read that php webpage and maybe write to it later on.
This web interface will be included with our current installer for the application or as a simple addon. The user should only have to click start server and it should just work serving the php pages from the installation directory.
I was playing with gwan, nginx, quickphp. Only the last one seems simple enough to work.
So my question is what do or would you use to achieve this? Are there alternatives to quickPHP?
Distribution. I'd also like to have something we can include in the installer. I dont want the user to have to do and download any additional apps.
I know you said PHP, you also mentioned your app is written in C#.
You might want to take a look at aspnetserve if you are willing to write the web part in .NET. It might be possible to use PHP with it, but I don't know.
Either way I have found it very useful in several projects.
If you can live with other types of server side scripting than php, Microsoft's Cassini server looks like potentially a very good match (.net based, source available, small, ...).
Oddly enough it's hard to find a "canonical" url for it but Googling or searching here on SO brings back plenty of links.
Edit: an at first sight surprising feature may be that out of the box Cassini only seems to listen to localhost (127.0.0.1). However, as explained here,
Cassini only listens to localhost requests (for security reasons) -- it
uses IPAddress.Loopback in the code. You can find the code in Server.cs and
you can change it to IPAddress.Any to enable access from other machines. Of
course, you'd be opening up the port for outside access, so you need to be
aware of the security implications.
Or go with UltiDev Cassini
EasyPHP
Lampp
For a light-light-weight server without installation you can look at nanoweb portable. I am not sure how performant it is though.
Are there alternatives to quickPHP? The user should only have to click start server and it should just work serving the php pages from the installation directory.
G-WAN works like this (zero-configuration): scripts and "edit & play".
And G-WAN v3.10+ supports C#, Java and PHP scripts (all natively).

APC not recommended for production?

I have started having problems with my VPS in the way that it would faill to serve the pages on all the websites. It just showed a blank page, or offered to download the php file ( luckily the code was not in the download file :) ).
The server was still running, but this seemed to be a problem with PHP, since i could login into WHM.
If i did a apache restart, the sites would work again.
After some talks with the server support they told me this is a problem with the APC extension witch they considered to be old and not recommended for production servers. So they removed it for now, to see if the same kind of fails would continue to appear.
I haven't read anywhere that APC could have some problems or that its not always recommended to use, quite the contrary ... everywhere people are saying to always use it.
The APC extension was installed ssh and is the latest version.
Edit:
They also dont recomend MemCache and say that a more reliable extension would be eAccelerator
Um APC is current tech and almost a must for any performant PHP site.
Not only that but it will ship as standard in PHP 6 (rather than being an optional module like it is now).
I don't know what your issue is/was but it's not APC being outdated or old tech.
I run several servers myself and the only time I have ever had trouble with APC was when trying to run it concurrently with Zend Optimizer. They don't work together so if I must use Optimizer (like if some commercial, third-party code requires it) I run eAccelerator instead of APC. Effectively 6 of one, half-dozen of another when it comes to performance but I really doubt APC is the problem here.
Just to add, memcached is only going to benefit you greatly if you are running multiple servers which need to access a shared data cache. Memcached does not do opcode caching like APC/eAccelerator/Xcache/etc.
The problem is not to do with APC. If APC had a problem, it would either show up in your php log file or you simply wouldn't be able to access your website until you adjusted APC. The problem is more likely with apache itself. I've experience the same problem as you with blank pages before and it was to do with mod_security playing up and preventing pages from being sent that looked "suspicious". Also, memory usage in apache is good at killing the server under load. I've also had experience with a web host that had compiled apache with a memory leak so every X amount of requests (say 100,000) the server would crash! Most annoying.
Your web host doesn't sound the most competent out there as they are giving some bad advice, most likely based on ignorance.
APC should be used on production (with the mstat check turned off on production, but on for development). You can get more stats about your apc setup while it's working by loading the apc status file that comes with it and you get a nice page like this: http://drupal.org/files/images/APC%20Status-1.png
Memcache is very heavily used as it's also distributed! The use for such is as follows:
APC is the fastest as it works most closely to php, but only works on the same server executing the PHP itself so it's use is limited in that scope. Used primarily as an opcode cache.
Memcache is like a very fast database spread over many computers working as one unit. However, a powercut will wipe the lot!!! Hence why they are heavily used to remove preasure from the persistant database. Facebook and many other sites have hundreds of servers running memcache.
My advice would be to find a web host that understands PHP. Fighting web hosts is hard work about whos right and whos wrong... until you find a good one ;)
Sounds to me like they are pushing a product that they probably have referral kickbacks on.
I run my own servers (have for a while) and I've never had this problem, not any MAJOR problems with MemCache.

Categories