mitras2
mitras2

Reputation: 73

IIS outbound rewite rule with condition based on the request (web.config)

I currently have the problem that IIS serves all my cookies with the sameSite=lax attribute after an update of .Net Framework on Windows Server (https://support.microsoft.com/en-us/help/4524419/kb4524419)

The problem is similar to how SameSite attribute added to my Asp.net_SessionID cookie automatically?

This breaks the functionality of most of the IFrames that are in use in webpages with another domain, as the browser does not send the ASP.Net Session-ID back to the server with subsequent requests.

Now while there are some suggestions in the above-mentioned thread they do not really work for me. This is due to Safaris nonstandard behavior. Safari on MacOSX and iOS 12.x treats the value "None" for the sameSite-attribute as unknown and therefore sets the value to "Strict" which again breaks the functionality of the IFrames for Safari users.

Now I wonder whether it is possible to define an outbound rewrite rule in the IIS web.config that first checks the request-header to see if the client is using a Safari browser. Depending on the Client browser, version different rewrite-outbound rules should change the cookies corresponding to what the browser expects.

Is it possible to write outbound rules with conditions based on the request? I did not find any documentation or website indicating this works...

Upvotes: 0

Views: 3099

Answers (1)

zemien
zemien

Reputation: 602

I modified upon several SO answers to come up with this URL rewrite that adds SameSite=None to session cookies, and also remove SameSite=None from all cookies for most incompatible browsers. The aim of this rewrite is to preserve the "legacy" behaviour pre-Chrome 80. It specifically covers the Safari on MacOSX and iOS 12.x scenario you mention.

Full write-up in my Coder Frontline blog:

<rewrite>
  <outboundRules>
    <preConditions>
      <!-- Checks User Agent to identify browsers incompatible with SameSite=None -->
      <preCondition name="IncompatibleWithSameSiteNone" logicalGrouping="MatchAny">
        <add input="{HTTP_USER_AGENT}" pattern="(CPU iPhone OS 12)|(iPad; CPU OS 12)" />
        <add input="{HTTP_USER_AGENT}" pattern="(Chrome/5)|(Chrome/6)" />
        <add input="{HTTP_USER_AGENT}" pattern="( OS X 10_14).*(Version/).*((Safari)|(KHTML, like Gecko)$)" />
      </preCondition>
    </preConditions>

    <!-- Adds or changes SameSite to None for the session cookie -->
    <!-- Note that secure header is also required by Chrome and should not be added here -->
    <rule name="SessionCookieAddNoneHeader">
      <match serverVariable="RESPONSE_Set-Cookie" pattern="((.*)(ASP.NET_SessionId)(=.*))(SameSite=.*)?" />
      <action type="Rewrite" value="{R:1}; SameSite=None" />
    </rule>

    <!-- Removes SameSite=None header from all cookies, for most incompatible browsers -->
    <rule name="CookieRemoveSameSiteNone" preCondition="IncompatibleWithSameSiteNone">
      <match serverVariable="RESPONSE_Set-Cookie" pattern="(.*)(SameSite=None)" />
      <action type="Rewrite" value="{R:1}" />
    </rule>
  </outboundRules>
</rewrite>

This should work for most ASP .Net and ASP .Net Core applications, although newer Frameworks have proper code and config options to let you control this behaviour. I would recommend researching all the options available to you before using my rewrite above.

Upvotes: 2

Related Questions