PHP FastCGI Impersonation Security: When to Enable Client Identity on IIS 7.5


2 views

When configuring PHP via FastCGI on IIS 7.5, Microsoft's documentation universally recommends setting fastcgi.impersonate = 1, which makes PHP execute scripts under the calling client's identity (typically IUSR). This raises legitimate security concerns for developers transitioning from ASP.NET environments.

In your described setup:

  • Dedicated application pool
  • ApplicationPoolIdentity as pool identity
  • Anonymous authentication (IUSR)

The critical difference from ASP.NET is how PHP applications typically handle file operations. Unlike ASP.NET's clear separation between IUSR (read) and app pool identity (write), PHP scripts often need unified permissions for both reading and writing files within the same execution context.

Enable impersonation when:

; php.ini configuration
fastcgi.impersonate = 1
fastcgi.logging = 0

1. Your application requires consistent permission context between web server and PHP file operations
2. You're using user-specific file operations (like per-user upload directories)
3. You need detailed audit trails of file operations

For better security without impersonation:

; Recommended permission structure
icacls "C:\webroot" /grant "IUSR:(OI)(CI)(RX)"
icacls "C:\webroot\uploads" /grant "IUSR:(OI)(CI)(M)"
icacls "C:\webroot\config" /deny "IUSR:(OI)(CI)(W)"

Consider these file system permission patterns instead of blanket impersonation:

  • Grant IUSR read-only to webroot
  • Create specific write folders with restricted permissions
  • Use ApplicationPoolIdentity for background processing

For a WordPress installation on IIS with mixed requirements:

# Directory permissions script
$webRoot = "D:\websites\wordpress"
$uploadDir = "$webRoot\wp-content\uploads"

# Base permissions
icacls $webRoot /grant "IUSR:(OI)(CI)(RX)"
icacls $uploadDir /grant "IUSR:(OI)(CI)(M)"
icacls "$webRoot\wp-config.php" /deny "IUSR:(OI)(CI)(W)"

# Special cases
icacls "$webRoot\wp-content\cache" /grant "ApplicationPoolIdentity:(OI)(CI)(M)"

Always evaluate:

  • Whether your PHP application actually needs per-file impersonation
  • The risk profile of your write-enabled directories
  • Alternative approaches like using separate service accounts for sensitive operations

Modern PHP frameworks often work better with explicit permission grants rather than full impersonation, reducing the attack surface while maintaining functionality.


When configuring PHP via FastCGI on IIS 7.5+, you'll encounter this critical setting in php.ini:

fastcgi.impersonate = 1

This setting determines whether PHP scripts execute under the calling client's identity (typically IUSR) or the application pool identity. Let's break down the implications.

In ASP.NET, we're accustomed to:

  • IUSR having read-only permissions
  • ApplicationPoolIdentity handling write operations

However, PHP applications often expect:

// Common PHP file operations that need proper permissions
file_put_contents('upload/test.txt', $data);
mkdir('cache/static_assets');

Enable impersonation when:

  • Your PHP app needs per-user file access tracking
  • You're migrating from Apache/mod_php environment
  • Using legacy PHP apps expecting $_SERVER['AUTH_USER']

For better security:

fastcgi.impersonate = 0

Then configure NTFS permissions:

icacls C:\wwwroot\app /grant "IIS AppPool\YourAppPoolName":(OI)(CI)(M)

Here's a secure setup for a uploads directory:

# php.ini
fastcgi.impersonate = 0

# Command line
icacls C:\wwwroot\uploads /grant "IIS AppPool\PHP-AppPool":(OI)(CI)(M)
icacls C:\wwwroot\uploads /grant "IUSR":(R)

Impersonation adds overhead for:

  • Each request's security context switch
  • Permission checks against IUSR instead of pooled identity

If you encounter errors, check:

# View effective permissions
accesschk.exe -uv IUSR C:\wwwroot
accesschk.exe -uv "IIS AppPool\PHP-AppPool" C:\wwwroot