When we set out to create VersionPress, we made a strategic decision to build it around Git. Git is an excellent version control system and many of the exciting features of VersionPress are powered by it, however, it is also means that the hosting is a bit of a challenge. Specifically, Git needs to be installed on a server and
proc_open() enabled to interact with it. In this blog post, I'm going to describe the issue in more detail, suggest some hosts that support VersionPress today and also share our plans in this area for the future.
The proc_open() issue
As mentioned above, the two toughest challenges for hosting VersionPress are:
- Git on the server
Though Git is not commonly installed on most hosts, it can be added quite easily – there's not much of an issue there. The
proc_open() function, however, is a different story because it can have security implications, depending on the hosting configuration.
Generally, the worry is that when a shared host allows
proc_open(), PHP scripts can run any process on the server which seems like a big security risk at first. It's also the reasoning I've heard most hosting companies use when they explain why they can't enable
proc_open() / support VersionPress.
However, when you look at the hosting landscape, you will find hosting companies (including highly professional ones) that have no problem enabling this function whatsoever. How comes?
This is what Daniel Lee from FastComet had to say (emphasis mine):
The ultimate goal is to always make sure that users are protected on a shared hosting environment. Of course, this is difficult sometimes, but there are multiple ways of achieving proper level of security on a shared server and still allow clients to use vital PHP functions they may need for their projects.
A few years back, one way of dealing with PHP functions that can be used for malicious activity was to enable safe_mode on the server. There are some advantages using it, as you can place restrictions on the environment, and limit the execution of binaries only within specifically allowed directories. This was one way of securing the environment, but it is hard to monitor when you have a large number of servers and clients. Moreover, proc_open() still allows you to provide your own environment and pass it to the new process. This could lead to many different issues with the server and it was considered as a security risk for the past few years so most hosting providers simply disable it.
Since day one, our primary goal was never limiting our clients on what they can do. As a developer, you would like to get your own environment and be able to code without having to ask every time when you need something enabled for your account. In most cases, you do not want to upgrade to expensive VPS or dedicated servers only so you can have your own customizable server. We believe that this should all be possible on a shared plan, as it is lower on cost and will allow you to test before you go big.
Our way of dealing with that is CloudLinux. CloudLinux is an operating system that allows better security, performance and real-time monitoring. One of the CloudLinux features that we enjoy the most is called CageFS and it is installed on all our shared hosting servers. CageFS encapsulates each account on the server into its own cage, with all system files, tools, etc. Why disabling PHP functions, when we can enable them for all clients and make sure they can only work in the client's cage and not globally on the server. This was adopted a few years back and since then, we have improvement in many different areas, including security, performance and customer satisfaction.
This is also the main reason why we enable proc_open() on our servers. There are no security concerns when it comes to the usage of the PHP function and we can safely enable it for all, without compromising the security level on any of our servers.
The other reply was from Jonas Pasche at Uberspace with some additional interesting points (again, emphasis mine):
First of all: Nearly any programming language happens to have some functions to start external programs within the context of the interpreter itself. In general, that's nothing security-related because, well: If a user is allowed to execute a PHP interpreter, why shouldn't he be allowed to execute any other program as well? In fact, I don't know about any other programming language which actually has the possibility to arbitrarily restrict functions; that's a PHP specialty.
The reason for this is that for long times many hosting providers choose to have PHP run directly in the Apache web server (“mod_php”). In that case PHP was running with the permissions of the webserver (not with your permissions), which basically meant that every user could read (and possibly write) any files the webserver has access to – which basically meant: Every file of every user. I guess because that – highly insecure – setup was that common, the PHP authors decided to implement a bunch of hacky security measures, like safe_mode, open_basedir … and disable_functions, because it would be totally pointless to restrict access of a user to some files outside his open_basedir, while at the same time allow him to execute arbitrary programs which don't have to obey those restrictions (as they're PHP specific).
All these hacky restrictions apply to PHP only. As soon as a hosting provider allows CGI or FastCGI scripts (to allow the user to use other languages like Perl, Python, Ruby, …) these restrictions are totally pointless; it's like having the front door locked with a bunch of extra locks while at the same time having the back door wide open.
In nowadays hosting setups, having PHP run as mod_php is highly unusual. Hosters tend to use PHP as php-fpm or as standalone FastCGI processes under strict privilege separation – that's what we do. That means that PHP processes don't run with the webserver's permissions, but with your permissions – which means that the basic Linux kernel filesystem capabilities take care of disallowing access to files of other users.
This privilege separation is a clean mechanism that applies to all processes a user runs – which renders all those hacky PHP-specific restriction mechanisms quite useless.
There's a slight point where such restrictions can still be of use, if it comes to application security. Let's say you install a content management system containing some security holes which can be remotely mis-used. An attacker could then use these holes to try to gain more/better access to your site, to place more sophisticated backdoors. PHP's disable_functions could be of a small use making that approach slightly harder because it renders some possibilities useless. Think of it as a very simple, very limited kind of sandboxing an application, where you can tell PHP “My application won't need proc_open so better forbid that function because it's only of use for possible attackers”. However, talking about security, that's the kind of security that you would implement yourself, to protect yourself (a little bit) against possible security holes in PHP-based software you installed yourself. If, on the other hand, the hosting provider is using that as a “security mechanism” I don't think that he has a good understanding what's happening on his servers. If he really thinks that disabling proc_open spares him from bad things to happen, he obviously still uses mod_php and you should run away … fast.
The main takeaway here is that there are shared hosts that allow proc_open() and care deeply about security at the same time. The focus on speed by FastComet and others also suggests that such setups do not suffer from performance issues.
All in all, while I am no expert when it comes to system administration, it seems to me that if a hosting provider wanted to support
proc_open() + Git and hence VersionPress, they could. With that being said, I also understand that it might not be easy / cost effective for them. What I wanted to understand – and share with you – is whether there are some fundamental issues with VersionPress in a shared hosting environment or whether it is a matter of other reasons, with a good chances that the situation will improve in the future. Fortunately, it is the latter.
How to host VersionPress today
If you want to host VersionPress today, you have a couple of options.
The most frequently used by our users is a custom server / VPS. That gives you infinite control over the environment so you can install whatever you want but it also comes at a cost – at minimum, you'll need to manage the environment yourself.
That's why people usually prefer managed / shared hosting services. We're creating a list of supported hosts on our docs site that you can look at and contribute to – just drop us a line at email@example.com. Thanks!
Looking into the future
Our ultimate goal is to run everywhere where WordPress can (well, with the exception of PHP 5.2 servers). For that, we are also exploring some other paths and one interesting option is to implement Git in pure PHP. That would mean that VersionPress would have no external dependencies and would work just fine everywhere. The main trouble here is that Git is a rather large piece of software and re-implementing even just the required parts of it is a lot of work. I believe this would be ideal as an open source / academic effort and we have already done some steps to start this. If it is something that would interest you, please get in touch, we need brave and great programmers!
There are also some other options so I am generally optimistic: while the hosting issue is a big one, the situation will improve over time and there are several ways to go about it. At the moment, please use one of the VersionPress-friendly hosting companies or a custom VPS.
Special thanks to FastComet's Daniel Lee and Uberspace's Jonas Pasche for their excellent contributions to this blog post.