Application Security and Development STIG Logging Requirements with IIS

The Defense Information Systems Agency (DISA) releases Security Technical Implementation Guides (STIGs). These are often-lengthy lists of recommended secure configurations. U.S. Department of Defense agencies are required to implement them.

Most STIGs are product-specific and detail very specific configuration settings (ex. set this Windows Server Group Policy setting to a specific value). The Application Security and Development (ASD) STIG is a broader and more generic STIG that applies to any application not covered by a product-specific STIG. It is generally used by developers inside the DoD when creating custom applications.

Dozens of the ASD STIG requirements relate to application logging. For web applications being hosted by IIS, I recommend leveraging the built-in IIS logging features. This accomplishes a few things:

  • Reduces the overall amount of code you have to write
  • Minimizes the risk of logging failures by separating logging from the application itself
  • If you aren’t the developer, it gives you a way to provide logging without having to request code changes from the vendor
  • Relies on functionality that the IIS STIG is already requiring you to have enabled anyway

If you have properly implemented the IIS STIG, you will be collecting at least the following fields:

  • Date
  • Time
  • Client IP Address
  • User Name
  • Method
  • URI Query
  • Protocol Status
  • Referrer
  • Request Header >> Connection
  • Request Header >> Warning
  • Request Header >> Authorization
  • Response Header >> Content-Type

Let’s take a look at a log entry and see how this information can help us meet our ASD STIG requirements:

2023-11-01 09:15:32 W3SVC1 MYSERVER 192.168.0.200 POST /BestWebAppEver/Offices/Edit/156143 - 443 EXAMPLE\johnnie.doe 192.168.15.12 HTTP/1.1 Mozilla/5.0+(Windows+NT+10.0;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/119.0.0.0+Safari/537.36 ASP.NET_SessionId=blahblahblah;+__RequestVerificationToken_blahblahblah /BestWebAppEver/Offices/Show/156143 myserver.example.com 200 0 0 72650 2903 491 keep-alive - - text/html;+charset=utf-8

If you are following best practices with our web app, we can learn a whole lot based on just the HTTP method, URI, and returned status code. For example, the above tells me:

  • POST means the user was submitting something that would result in a data change
  • The URI tells me that the user was editing the “Office” object with an ID of 156143
  • The “200” tells me the app returned an HTTP 200, which means the action was successful

The usefulness of these logs is based in large part on how consistent and descriptive the URIs are. If the application is based on an MVC framework, the URI queries/stems will usually tell you everything you need to know. In the above example, we were able to tell exactly what record was edited based purely on the URI. The username field told us who executed the action, and the HTTP response code told us it was successful.

A good web app will return an HTTP 403 if somebody does something their account forbids. If you are ingesting your IIS logs into a SIEM (and you really should), you can now build dashboards and processes for failed actions in your web apps simply by filtering for HTTP 403s. For example, imagine an automated alert that triggers if any given user triggers three or more HTTP 403s in a ten minute timespan. You will be able to easily see from these IIS logs exactly what the user was trying.

All of the above means I can satisfy at least 39 ASD STIG requirements just via IIS logging:

STIG-IDSTIG Quick Description
APSC-DV-000520Privileged functions
APSC-DV-000610Centralized control over what to audit
APSC-DV-000670Event must include date and time
APSC-DV-000680HTTP User-Agent, Referer, and Method headers
APSC-DV-000690Client IP address
APSC-DV-000700Username
APSC-DV-000710Grant privileges
APSC-DV-000720Access security objects
APSC-DV-000730Access security levels
APSC-DV-000740Access categories of information
APSC-DV-000750Modify privileges
APSC-DV-000760Modify security objects
APSC-DV-000770Modify security levels
APSC-DV-000780Modify categories of information
APSC-DV-000790Delete privileges
APSC-DV-000800Delete security levels
APSC-DV-000810Delete application database security objects
APSC-DV-000820Delete categories of information
APSC-DV-000830Logon attempts
APSC-DV-000840Privileged activities
APSC-DV-000860Access to objects
APSC-DV-000910Initiate session auditing on startup
APSC-DV-000960Data access
APSC-DV-000970Data modification
APSC-DV-000980Date and time
APSC-DV-000990Relevant component
APSC-DV-001000Relevant application and client IP
APSC-DV-001010Success or failure
APSC-DV-001020Username
APSC-DV-001030Detailed logging for privileged requests
APSC-DV-001050Centralized control over what to audit
APSC-DV-001250Must use OS clock for logging
APSC-DV-001260Timestamps map to UTC
APSC-DV-001270Timestamps granular to one second
APSC-DV-001280Audit data access restrictions
APSC-DV-001290Audit data modification restrictions
APSC-DV-001300Audit data deletion restrictions
APSC-DV-001420Audit configuration changes
APSC-DV-003360Log concurrent logons from separate systems