When migrating from IIS 6 to IIS 7.5 with Helicon ISAPI Rewrite 3, many developers encounter unexpected 403.18 Forbidden errors during URL rewrites between application pools. This behavior stems from fundamental architectural changes in IIS's security model.
IIS 7.5 implements stricter application pool isolation by default. Unlike IIS 6 where requests could flow more freely between pools, IIS 7.5 treats each application pool as a separate security boundary. The 403.18 error specifically indicates the server is configured to forbid requests between application pools.
// Sample rewrite rule that would work in IIS 6 but fail in IIS 7.5
RewriteRule ^/subapp/(.*) http://localhost:80/subapp/$1 [P]
Three viable approaches exist for maintaining rewrite functionality:
1. Using ARR (Application Request Routing)
Microsoft's recommended solution involves installing the Application Request Routing module:
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxy" stopProcessing="true">
<match url="^subapp/(.*)" />
<action type="Rewrite" url="http://localhost:8080/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
2. Enabling Double-Hop Authentication
For scenarios requiring ISAPI_Rewrite compatibility:
1. Set "loadUserProfile" to true in application pool settings
2. Configure SPN (Service Principal Names) for proper Kerberos delegation
3. Enable "useAppPoolCredentials" in web.config:
<system.web>
<identity impersonate="true" />
</system.web>
3. Shared Configuration Approach
When applications can share security context:
<application path="/subapp" applicationPool="MainAppPool">
<virtualDirectory path="/" physicalPath="C:\sites\subapp" />
</application>
Each solution carries different performance characteristics:
- ARR adds about 5-15ms overhead per request
- Double-hop authentication requires additional security handshakes
- Shared pools reduce isolation benefits
Enable failed request tracing to identify exact failure points:
%windir%\system32\inetsrv\appcmd.exe set config
-section:system.webServer/tracing
/traceFailedRequestsLogging.enabled:"True"
/commit:apphost
When migrating from IIS 6 to IIS 7.5, many developers encounter unexpected 403.18 errors during URL rewrites between application pools. This security enhancement in IIS 7.5 creates strict boundaries between application pools by default.
The fundamental difference lies in IIS 7.5's security model. While IIS 6 allowed more permissive cross-pool communication, IIS 7.5 implements strict isolation. Each application pool runs as a separate worker process (w3wp.exe) with distinct security identities.
<system.webServer> <security> <authentication> <anonymousAuthentication enabled="true" /> </authentication> </security> </system.webServer>
We have multiple approaches to resolve this while maintaining security:
Option 1: Shared Configuration
Configure all application pools to use the same identity:
1. Open IIS Manager 2. Select Application Pools 3. Right-click each pool → Advanced Settings 4. Set Identity to same account (e.g., ApplicationPoolIdentity) 5. Enable "Load User Profile" if needed
Option 2: URL Rewrite Module Configuration
For Helicon ISAPI Rewrite 3 users migrating to IIS 7.5:
RewriteEngine on RewriteBase / RewriteCond %{HTTP_HOST} ^example\.com$ [NC] RewriteRule ^path/(.*)$ http://localhost:port/$1 [P,L]
Note the [P] flag for proxy functionality
Option 3: ARR (Application Request Routing)
A more scalable solution using Microsoft's recommended approach:
<system.webServer> <rewrite> <rules> <rule name="Proxy" stopProcessing="true"> <match url="^service/(.*)" /> <action type="Rewrite" url="http://localhost:8081/{R:1}" /> </rule> </rules> </rewrite> </system.webServer>
When all else fails, verify these NTFS permissions:
icacls "C:\inetpub\wwwroot" /grant "IIS AppPool\AppPool1":(OI)(CI)(RX) icacls "C:\inetpub\wwwroot" /grant "IIS AppPool\AppPool2":(OI)(CI)(RX)
Enable failed request tracing to capture detailed rewrite behavior:
1. Server level → Failed Request Tracing 2. Create new rule for status code 403 3. Examine FREB logs for authentication issues