25 Years of Programming
An open source source for C, C++, OWL, BASIC, MDB, XLS, DOT, and more...
Home   Projects   Sitemap   Search   Blog   Forum+Chat   About Us   Privacy   Terms of Use   Feedback   FAQ   Images   Services   Payments   Humor   Music  

What is the difference between PHP as an Apache module and as CGI?

A computer program is a list of instructions understandable by a computer that allow it to perform a task.

As a simple example, imagine a computer program that reads or receives a block of text, translates all the letters to upper case, and outputs the result.

There are two ways we could design this program to be run:

We could make it a standalone console program so that we can type its name on the command line and have it convert any text we give it to upper case. When a standalone program like this is installed on a server, it's sometimes called a CGI, in a sense, a fancy name for a standalone program.

Or we could incorporate it into another, larger, program while we're building the larger program, so that conversion of text to upper case becomes one of its built-in features. When a program is turned into a subprogram in this way, it is sometimes said to be a module of the larger program.

PHP is a program like our upper case conversion program except that it's much larger and more complicated, but its function is similar. It receives some input text (a PHP script or an HTML file with PHP instructions embedded in it), and it outputs some result text. The operations that it performs between input and output might be very simple or very complicated or somewhere in between.

If we're building an installation of the Apache web server, and we want to be able to use the capabilities of PHP, we can do it either of the two ways:

PHP as Apache module

Apache is designed so that other programs can be incorporated into it as part of itself, and PHP is designed so that it can be used this way. When the two programs are merged together, the things PHP can do become built-in features of Apache, and PHP is said to be a module of Apache, or an Apache module. While Apache is processing a file, the execution of PHP code to produce the result text is something that it now inherently knows how to do using only the code that's been built into it.

PHP as a CGI

Alternatively, we could install the standalone version of PHP on the server, separately from Apache. In this case, Apache doesn't know how to execute PHP code. However, one computer program can call another program so that it launches and runs. Apache knows how to call an outside program and receive the output it produces. In this case, Apache doesn't execute the PHP code itself. Instead, it hands off the file to the PHP interpreter (program). PHP executes the code and sends the resulting text, if any, back to Apache for further processing and to send to whoever requested it.

Configurability comparison

The main PHP configuration file is called php.ini. On a shared server, the master php.ini file is in a location that is not accessible by any of the user accounts.

The two different server configurations provide differing options for whether you can override settings in the master php.ini and whether you can specify equivalent settings in an alternative location.

PHP as Apache module: Because PHP is part of Apache, you can specify some PHP configuration settings in the .htaccess Apache configuration file, for Apache to pass through to its PHP module. On a shared server, this usually means that you can override some of the master php.ini configuration settings in your local .htaccess files.

PHP as CGI: PHP is a completely separate program from Apache, so Apache can't manage the PHP configuration settings, and you can't set them in .htaccess. On a shared server, if it is not running suPHP to allow users to have an additional local php.ini file, this may mean that individual users cannot override any PHP settings except for the few that can be set within a PHP script using PHP program code.  

Efficiency comparison

PHP as Apache module: PHP is already loaded and ready to run at all times, so this option is faster.

PHP as CGI: The PHP program is read from disk and launched every time Apache needs its services. On a site that uses PHP at all, PHP usually must be launched and run for every requested page. It is said that FastCGI can help make PHP as CGI run faster.  

Security comparison

Background: User Permissions

The Linux and Windows operating systems allow for the creation of "users" (human or virtual) on the system. Each user has lists of files and folders that it is allowed or not allowed to access, and a list of programs that it is allowed or not allowed to run. These access control settings are called permissions.

You, when you opened an account with your webhost, were assigned a userID, which is also the system user that you are known as on your Linux server. There are lists of things that you can and cannot do on the server, and you, your userID, has ownership of all the files you created.

When a program runs on the computer, it runs as though it is one of the system's users (for example, the person who launched it), and it has the same permissions as that user, the same list of files it can access, and the same list of actions it is allowed or not allowed to perform.

PHP by default runs as the same user as Apache, which is often the Linux user called "nobody".

Linux does not allow one user to write into the files owned by another user. You are userID, and PHP is nobody, and therefore by default PHP is unable to write into any of the files in your website.

That is why, if you need PHP (nobody) to write to your files, you must loosen the permissions to allow other users write access to your files, by setting the file permissions to 666 and folder permissions to 777.

That can be a security risk because it gives write access not just to nobody, but also to all the other userIDs on the computer. On a shared server, those are the other user accounts on the server. Thus, if any account on the server is compromised by a hacker, they may be able to reach across into your site. Contrary to a common belief, the permissions don't allow "anybody in the world" to write to your files unless they use some other means to break into the server first. 

A shared server has just one instance of Apache to handle all the accounts (websites). Apache runs continuously and can't be restarted without causing server downtime, so its userID of "nobody" never changes.

PHP as Apache module: Since PHP is part of Apache, it launches only once and runs continuously, so there is no opportunity to make it run as any other user. As nobody, it can't write to your files, so if you need it to do that, you must make the permissions adjustments described above and either accept the potential security risk or try to find a way to reduce it. One way to reduce it is to make your folders or files writable by others only for the shortest possible time, when PHP actually needs to do the writing. The rest of the time, keep the permissions locked down.  

PHP as CGI: Since PHP is freshly launched each time it's needed, there is an opportunity to run it as a different user with each launch. See the next section.

suPHP provides greater security at a cost of speed

There is an Apache module/program called suPHP, which causes a CGI installation of PHP to run, each time it is launched, as the user whose account caused it to be launched: your userID.

With this configuration, PHP runs as you, with the same permissions as you, and is able to write into your files without your having to loosen the permissions first.

In addition, just like you, it does not have permission to write into anybody else's account on your shared server, so that if one account on the server is compromised, it does not automatically get access through PHP to other files and folders in other accounts.

With suPHP, it is also possible for each user on a shared server to have their own php.ini file with PHP configuration settings to override the ones in the master php.ini.

The downside is that suPHP is slower because it requires the PHP as CGI configuration.

Further reading

  • Discussion of security issues in the PHP Manual.
  • Complete list of php.ini configuration options, and table for understanding the locations where each can be set (php.ini, .htaccess, etc.).

Notes

  1. Sometimes when cleaning up a hacked website, you might run across a file that was installed by the hack and that you can't edit or delete. This is usually because the file and/or the folder it is in were created by PHP which was running as nobody. That makes nobody the owner. When you are working on your site in control panel or by FTP, you are your userID, not nobody, so you are denied access. The solution is to create and run a PHP script that does the editing or deletion. Your PHP script runs as nobody, so it is allowed access to the folder and file.
     
  2. The security advantages of PHP as CGI and suPHP were demonstrated by the April 2010 mass attack on WordPress blogs at a large web hosting company. A malicious user who purchased hosting at the company was able to read the wp-config.php files of other users on the same server. Because wp-config.php contains in plain text the credentials for accessing the WordPress MySQL database, the hacker was able to access the databases and inject malicious code.

    Because the company was running PHP as CGI with suPHP, the solution was for customers to make their wp-config.php file unreadable by other users by setting the Linux permissions to 640. That gave read/write permissions to the owner (and to PHP running as the owner), read permissions to the group (irrelevant for our purposes), and NO permissions at all, not even read permissions, to other users on the same server.

    Contrast that with PHP as Apache module: in order for PHP to read wp-config.php, read permissions would have to be granted to world/other (644), but if PHP can read it, so can everybody else on the same server because granting permissions to the one automatically grants them to everybody. Thus, if the company's servers had been configured that way, there would have been no solution except to get rid of the malicious account (which undoubtedly they did) and try to prevent new malicious users from creating accounts and doing the same thing. In other words, not a technological solution but an entirely human one.  
     
  3. But if #2 above seems to make the choice look simple, there's a different situation that makes PHP as Apache module look good: a Remote File Inclusion is a type of exploit that tricks one of your PHP scripts into fetching script code from a remote site and running it. With PHP as CGI, the malicious script has owner-level permissions for every file and folder in your site, just like you do, so it can potentially modify every file. But with PHP as Apache module, the malicious script is just nobody, like every other PHP script, and is more limited in the amount of damage it can do. It can't put new files in folders unless they have 777 permissions, and it can't modify files unless they have 666 permissions.

    You could summarize the differences like this:

    PHP as CGI with suPHP: You are very securely walled off from the other accounts on your shared server. If another account gets hacked, it probably cannot affect your site at all. However, if your account gets hacked, the hacker has complete freedom to wreak total havoc inside your site because they can use PHP to access/change anything they want. Since PHP runs as you, you have no ability to protect your files from a rogue PHP script.

    PHP as Apache module: You are not walled off from other accounts on your shared server. If another account gets hacked, PHP can be used to read your files, and any file or folder that you can write to using PHP, the other account can, too. However, if your account gets hacked, the majority of your files remain protected from malicious modification by PHP, because PHP when running inside your account doesn't have any greater privileges than it already has all of the time. It is only nobody, and most of your files are owned by your userID, so it can't change them or add files to your site. It can only write to your 666 files and can only put new files into your 777 folders.

    Corollary:

    There is a common type of attack in which a malicious PHP script runs through a website opening every file with index in its name (index.htm, index.html, index.php...) and stuffs malicious code (iframes or scripts) into each of them. This type of attack is normally not possible with PHP as Apache module because the files are protected by their permissions settings (unless the permissions settings were wrong). If an Apache module configured website suffers this type of attack, it must have happened through FTP password theft, with the attacker downloading the files, modifying them, and re-uploading them. While using FTP, the attacker is acting as your userID and therefore has the ability to change the files. They couldn't have done it, in this case, with PHP.
     
  4. Regardless whether your PHP is configured as CGI or as a Apache module, you can protect yourself against RFI attack with an even more basic method: your PHP scripts should be written so that data provided by the user is always validated before use, to prevent malicious data getting into the script in the first place.

Questions and comments are welcome in the discussion forum.


 

Valid HTML 4.01 Transitional
Yahoo! Search
Search the web Search this site
Valid CSS