How to Log POST Data and Full HTTP Requests in IIS for Debugging and Analysis


19 views

By default, IIS doesn't log POST data in its request logs due to security and performance considerations. The standard W3C logging format only captures metadata like:

  • Request URL and query string
  • HTTP method (GET/POST/PUT etc.)
  • Response status codes
  • Client IP and user agent

For complete request capture including POST bodies, use Failed Request Tracing (FRT):

<configuration>
  <system.webServer>
    <tracing>
      <traceFailedRequests>
        <add path="*">
          <traceAreas>
            <add provider="ASP" verbosity="Verbose" />
            <add provider="ASPNET" verbosity="Verbose" />
            <add provider="ISAPI Extension" verbosity="Verbose" />
            <add provider="WWW Server" verbosity="Verbose" />
          </traceAreas>
          <failureDefinitions statusCodes="200-999" />
        </add>
      </traceFailedRequests>
    </tracing>
  </system.webServer>
</configuration>

For production environments, consider implementing a custom IIS module:

public class RequestLoggerModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.BeginRequest += (sender, e) => {
            var app = (HttpApplication)sender;
            if (app.Request.HttpMethod == "POST")
            {
                using (var reader = new StreamReader(app.Request.InputStream))
                {
                    string postData = reader.ReadToEnd();
                    // Reset stream position for other handlers
                    app.Request.InputStream.Position = 0;
                    LogToDatabase(app.Request.Url, postData);
                }
            }
        };
    }

    private void LogToDatabase(Uri url, string data)
    {
        // Implementation for your storage backend
    }
}

Add these server variables to your W3C logging fields for more context:

<configuration>
  <system.applicationHost>
    <sites>
      <site name="Default Web Site" id="1">
        <logFile logExtFileFlags="Date, Time, ClientIP, UserName, ServerIP, Method, 
                                 UriStem, UriQuery, HttpStatus, Win32Status, 
                                 BytesSent, BytesRecv, TimeTaken, ServerPort, 
                                 UserAgent, Cookie, Referer, ProtocolVersion, 
                                 Host, HttpSubStatus" />
      </site>
    </sites>
  </system.applicationHost>
</configuration>
Solution Pros Cons
ELK Stack Centralized logging, powerful analysis Complex setup
GoAccess Real-time reporting No POST body capture
ASP.NET Middleware Full control Development overhead

When logging sensitive POST data:

  • Implement data masking for passwords/PII
  • Use encrypted storage for logs
  • Set proper retention policies
  • Consider PCI DSS/HIPAA compliance requirements

IIS by default doesn't log POST request bodies or full HTTP requests in its access logs. This becomes problematic when debugging:

2023-01-01 12:34:56 192.168.1.1 POST /api/submit - 443 - 192.168.1.2 Mozilla/5.0 200 0 0 342

The log shows basic information but lacks the crucial POST payload that might contain error details.

You'll need to configure IIS to capture more detailed information:

%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/asp /logErrorRequests:true /commit:apphost

This powerful IIS feature can capture the full request:

  1. Open IIS Manager
  2. Select your site
  3. In Features View, double-click "Failed Request Tracing Rules"
  4. Add new rule with status code 200-999
  5. Select all content types

Sample configuration in applicationHost.config:

<traceProviderDefinitions>
    <add name="WWW Server" guid="{3a2a4e84-4c21-4981-ae10-3fda0d9b0f83}">
        <areas>
            <add name="Authentication" value="2"/>
            <add name="Security" value="4"/>
            <add name="Filter" value="8"/>
            <add name="StaticFile" value="16"/>
            <add name="CGI" value="32"/>
            <add name="Compression" value="64"/>
            <add name="Cache" value="128"/>
            <add name="RequestNotifications" value="256"/>
            <add name="Module" value="512"/>
        </areas>
    </add>
</traceProviderDefinitions>

For more control, create a custom IHttpModule:

public class RequestLoggerModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.BeginRequest += (sender, e) => {
            var request = ((HttpApplication)sender).Request;
            if (request.HttpMethod == "POST")
            {
                using (var reader = new StreamReader(request.InputStream))
                {
                    var postData = reader.ReadToEnd();
                    // Log to custom file or database
                    File.AppendAllText(
                        @"C:\logs\iis_postdata.log", 
                        $"{DateTime.UtcNow:o}|{request.RawUrl}|{postData}{Environment.NewLine}"
                    );
                    request.InputStream.Position = 0;
                }
            }
        };
    }
    
    public void Dispose() { }
}

Consider these tools for enterprise solutions:

  • ELK Stack with IIS module
  • Splunk HTTP Event Collector
  • Microsoft's Advanced Logging extension

Remember that logging POST data may capture sensitive information:

  • Always encrypt log files containing sensitive data
  • Implement proper access controls
  • Consider masking sensitive fields (credit cards, passwords)