iis-docs icon indicating copy to clipboard operation
iis-docs copied to clipboard

URL Rewrite Module caching behavior doesn't match description

Open mdmower-csnw opened this issue 2 years ago • 0 comments

I ran into several issues while referencing URL Rewrite Module Configuration Reference: Interaction with IIS Output Caching. These issues have security implications for server variables like CERT_SERIALNUMBER that are set by SSL client certificates.

  1. Despite this claim...

    The module cannot enable output caching if it has been disabled by IIS configuration or by any other module in the IIS pipeline.

    I observed URL Rewrite Module caching when Output Caching was disabled at both the server-level and site-level in IIS 10.0:

    • Output Caching > Edit Feature Settings... > Enable cache = unchecked
    • Output Caching > Edit Feature Settings... > Enable kernel cache = unchecked
  2. In item 3, this claim is misleading...

    If a rewrite rule set uses any server variable not mentioned in the above list, the rule set is considered unsafe for output caching.

    Through trial and error, I found that the server variable has to be included in the <conditions> for unsafe cache handling to be applied. For example, despite CERT_SUBJECT, CERT_SERIALNUMBER, and CERT_ISSUER appearing in the <serverVariables> below, URL Rewrite Module caches the output:

    <rewrite>
      <rules>
        <clear />
        <rule name="MyRule">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
          <serverVariables>
            <set name="HTTP_X_TESTING_CERT_SUBJECT" value="{CERT_SUBJECT}" />
            <set name="HTTP_X_TESTING_CERT_SERIALNUMBER" value="{CERT_SERIALNUMBER}" />
            <set name="HTTP_X_TESTING_CERT_ISSUER" value="{CERT_ISSUER}" />
          </serverVariables>
          <action type="None" />
        </rule>
      </rules>
    </rewrite>
    

    The only way I was able to vary caching (I was never able to disable caching) was to include CERT_SUBJECT, CERT_SERIALNUMBER, and CERT_ISSUER in <conditions>:

    <rewrite>
      <rules>
        <clear />
        <rule name="MyRule">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
            <add input="{CERT_SUBJECT}" pattern=".*" />
            <add input="{CERT_SERIALNUMBER}" pattern=".*" />
            <add input="{CERT_ISSUER}" pattern=".*" />
          </conditions>
          <serverVariables>
            <set name="HTTP_X_TESTING_CERT_SUBJECT" value="{CERT_SUBJECT}" />
            <set name="HTTP_X_TESTING_CERT_SERIALNUMBER" value="{CERT_SERIALNUMBER}" />
            <set name="HTTP_X_TESTING_CERT_ISSUER" value="{CERT_ISSUER}" />
          </serverVariables>
          <action type="None" />
        </rule>
      </rules>
    </rewrite>
    
    
  3. In item 3, this claim is misleading...

    This means that the URL Rewrite Module will disable kernel mode caching for all requests whether the request URLs were rewritten or not.

    Through trial and error, I observed that <add input="{CERT_SUBJECT}" pattern=".*" /> alone is insufficient to prevent caching. Every server variable that should vary the response must appear in the rule set, for example: CERT_SUBJECT, CERT_SERIALNUMBER, and CERT_ISSUER. I eventually understood that this must be the distinction between kernel mode caching and user mode caching, but examples would have made this clearer.

mdmower-csnw avatar Nov 16 '23 18:11 mdmower-csnw