Step 3: Configure PHP Application Security
Updated: May 4, 2012
Applies To: Windows Server 2012 R2, Windows Server 2012
In this last step in building a PHP website on IIS, you configure PHP settings, web server settings, and PHP application settings that improve your website security.
The following procedure shows you how to configure PHP settings in the php.ini file. For information about security-related PHP settings, see 3.1. PHP Configuration Settings for Security.
To configure a PHP setting for security
In Windows Explorer, open your PHP installation folder, for example C:\PHP.
In a text editor, open the php.ini file.
Search the file for the setting you want to change.
If the setting is commented out (line begins with a semicolon [;]), delete the semicolon and set the value. If you can’t find the setting, add the line to the end of the file.
Save and close the php.ini file.
Recycle the IIS Application Pools for PHP to pick up the configuration changes.
This section shows how to configure several web server and application settings for IIS. These settings include isolating web applications, enabling per-site PHP configurations, and using request filtering. For more information about web server and PHP application security settings, see 3.2. Web Server and PHP Application Security.
Implement the following recommendations to isolate websites and web applications on your server.
Use one application pool per website or web application.
Limit access to site folders and files to the application pool identity.
Set up a separate PHP temp folder per site and only give access to the application pool identity.
Make sure to set an ACL (access control list) on each site root to allow only access to the application pool identity.
If you have more than one application per application pool, consider creating enough application pools and moving some of the applications to the new pools.
To create an application pool
Open IIS Manager.
In the Connections pane, click Application Pools.
In the Actions pane, click Add Application Pool.
In the Name box, type a unique name for the application pool.
Under .NET Framework version, select No Managed Code.
Select the Managed pipeline mode. The Integrated mode is recommended.
To move an application to another application pool
Open IIS Manager.
In the Connections page, select the website or web application you want to move.
In the Actions pane, click Basic Settings.
On the Edit Site dialog, click Select to open the Select Application Pool dialog, and then select the application pool from the Application pool menu.
Click OK to close the Select Application Pool dialog, and click OK to close the Edit Site menu.
To add an application pool identity to a folder or file ACL
Open Windows Explorer and navigate to the folder or file.
Right click the folder or file, and then click Properties.
Select the Security tab, and then click Edit.
Click Add, click Locations, and select your server as the location to search.
In the Enter the object names to select box, type IIS APPPOOL\applicationPoolName, where applicationPoolName is the application pool identity.
Click OK, click OK, and click OK again to close the dialogs.
When you have multiple PHP applications on an IIS web server, you can improve security by configuring a PHP process pool and a php.ini file for each application. This section explains how to configure process pools and multiple pnp.ini files by using an applicationHost.config file.
When each website has its own application pool, which is a recommended practice on IIS, it is possible to associate a dedicated FastCGI process pool with each website. This association is done in the fastCgi section of the applicationHost.config file. A FastCGI process pool is uniquely identified by the combination of fullPath and arguments attributes of the application element. To create several FastCGI process pools for the same process executable, such as php-cgi.exe, use the arguments attribute to distinguish the process pool definitions. With php-cgi.exe processes, use the command line switch "-d" to define an INI entry for a PHP process. And use this switch to set a PHP setting that makes the arguments string unique.
For example, if there are two Web sites "website1" and "website2" that must have their own set of PHP settings, define the FastCGI process pools as follows:
<fastCgi> <application fullPath="C:\PHP\php-cgi.exe" arguments="-d open_basedir=C:\Websites\Website1" /> <application fullPath="C:\PHP\php-cgi.exe" arguments="-d open_basedir=C:\Websites\Website2" /> </fastCgi>
In this example the PHP setting open_basedir is used to distinguish between the process pool definitions. The setting also enforces that the PHP executable for each process pool can perform file operations only within the root folder of the corresponding website.
Therefore, the PHP handler mapping for website1 is as follows:
<system.webServer> <handlers accessPolicy="Read, Script"> <add name="PHP via FastCGI" path="*.php" verb="*" modules="FastCgiModule" scriptProcessor="C:\PHP\php-cgi.exe|-d open_basedir=C:\Websites\Website1" resourceType="Unspecified" requireAccess="Script" /> </handlers> </system.webServer>
And the handler mapping for website2 is as follows:
<system.webServer> <handlers accessPolicy="Read, Script"> <add name="PHP via FastCGI" path="*.php" verb="*" modules="FastCgiModule" scriptProcessor="C:\PHP\php-cgi.exe|-d open_basedir=C:\Websites\Website2" resourceType="Unspecified" requireAccess="Script" /> </handlers> </system.webServer>
When the PHP process starts, it determines the location of the configuration php.ini file by using various settings. The PHP documentation provides a detailed description of the PHP startup process. One of the places where the PHP process searches for the php.ini location is the PHPRC environment variable. If the PHP process finds a php.ini file in the path that is specified in this environment variable, it will use it. Otherwise, the PHP process will revert to using the default location of the php.ini file. This environment variable can be used to allow hosting customers to use their own versions of php.ini files.
For example, if there are two websites, "website1" and "website2," that are located at the following file paths: C:\WebSites\website1 and C:\WebSites\website2, you can configure the php-cgi.exe process pools in the fastCgi section of the applicationHost.config file as follows:
<fastCgi> <application fullPath="C:\PHP\php-cgi.exe" arguments="-d open_basedir=C:\Websites\Website1"> <environmentVariables> <environmentVariable name="PHPRC" value="C:\WebSites\website1" /> </environmentVariables> </application> <application fullPath="C:\PHP\php-cgi.exe" arguments="-d open_basedir=C:\WebSites\Website2"> <environmentVariables> <environmentVariable name="PHPRC" value="C:\WebSites\website2" /> </environmentVariables> </application> </fastCgi>
This way website1 can have its own version of the php.ini file that is located in the C:\WebSites\website1, while website2 can have its own version of the php.ini file that is located in C:\WebSites\website2. This configuration also ensures that if a php.ini file cannot be found in the location that is specified by the PHPRC environment variable, then PHP will use the default php.ini file that is located in the same folder where the php-cgi.exe is located.