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


2 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)