Not sure which is TRWTF - Me or IIS web.config



  • Here's what I want to do: If anyone accesses our site using HTTP, redirect to HTTPS. If they access us using any host name other than www.domain.co.uk then redirect to that.

    I have the following rules in web.config on our live site:

        <rule name="HTTPS Only" enabled="true" stopProcessing="true">
            <match url="(.*)" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                <add input="{HTTP_HOST}" pattern="^localhost$" negate="true" />
                <add input="{HTTP_HOST}" pattern="^(?:\d+\.){3}\d+$" negate="true" />
                <add input="{HTTPS}" pattern="off" />
            </conditions>
            <action type="Redirect" url="https://www.domain.co.uk/{R:1}" appendQueryString="true" />
        </rule>
        <rule name="Canonical Host HTTPS" enabled="true" stopProcessing="true">
            <match url="(.*)" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                <add input="{HTTP_HOST}" pattern="^(?:www|testing)\.domain\.co\.uk$" negate="true" />
                <add input="{HTTP_HOST}" pattern="^localhost$" negate="true" />
                <add input="{HTTP_HOST}" pattern="^(?:\d+\.){3}\d+$" negate="true" />
            </conditions>
            <action type="Redirect" url="https://www.domain.co.uk/{R:1}" appendQueryString="true" />
        </rule>
    

    When I upload it, everything works as expected, both from the browser and through using Network Tools to check the headers. Then, some time later (around 10 minutes), accessing https://www.domain.co.uk results in an infinite redirect loop! Network Tools confirms this as well.

    I thought I had made a mistake and had made various changes over the last few days, each time believing I'd fixed it. Then it would break again. Today, just out of spite, I merely uploaded the exact same web.config to the live site without any changes, and it works! And then, after around 10 minutes, it stops working again! I can reproduce it every time!

    Have I found a bug in IIS or am I dong it wrong? As a side-note, sessions last for hours, so I don't think that's anything to do with it.



  • Oh shit, I did exactly this once, but I no longer have the code. I remember it being a pain in the ass, and thinking, "isn't this a really fucking common use-case to be such a pain in the ass?"

    Sorry.



  • Well, glad I'm not alone with this! I've tried to rewrite this logic in a few ways, but yeah... I've had a canonical www domain rule up for ages with no issues, so I'm perplexed.



  • My problem is I did it on the web server's IIS config and so while I have the web.config of the project, I don't have the IIS config stuff I put in.

    I couldn't put it in the web.config of the project because then it would break testing and I'm too lazy to maintain two separate web.configs. WELL NOW THAT'S BIT ME IN THE ASS.

    EDIT: IIRC, and it's been years so grain of salt, I had to set up a rule for the URLs I actually wanted, put a "stop processing = true" on that, then set up a rule that matches everything to do the redirect.



  • Hmm.... Seems to be playing nice at the moment. How about I leave it as it is on a Friday and see if I get any support calls over the weekend!



  • That is the key to software quality success!



  • Slight derivative of this?

    <rule name="Redirect all the things" enabled="true" stopProcessing="true">
            <match url="(.*)" />
            <conditions logicalGrouping="MatchAny">
                <add input="{SERVER_PORT_SECURE}" pattern="^1$" />
                <add input="{SERVER_PORT_SECURE}" pattern="^0$" />
            </conditions>
            <action type="Redirect" url="https://www.domain.co.uk/{R:1}" appendQueryString="true" redirectType="Permanent" />
        </rule>
    


  • That looks right off-hand, but you need to add in a rule to not redirect traffic already on the correct domain and do a "stopProcessing" on it. Otherwise, you'll end up redirecting legit traffic.



  • So... Match {SERVER_PORT_SECURE} = 1 and match {SERVER_PORT_SECURE} = 0... so redirect everything? Sounds like a WTF to me. And why use {SERVER_PORT_SECURE} over {HTTPS}?



  • Yeah I was confused about that too, but I figured I don't know enough about IIS config to make a fuss.



  • That's what his code sample is doing, it's redirecting everybody.

    I was saying you need to make sure the people who aren't supposed to be redirected are matched first, and dump out of the rules if so. So they don't end up re-redirected back to where they were. Which is either harmless, or a nasty redirect loop, I'm not sure which...



  • @blakeyrat said:

    That's what his code sample is doing, it's redirecting everybody.

    Why then do you need to put <conditions> tag at all? Wouldn't removing it achieve the same purpose?



  • Redirecting everything seemed far simpler than trying to fuck up match possible variations of the domain.

    I mean, if you get a request for nottherightdomain.com on your server, DNS is all kinds of FUBAR so do you really care?

    As Blakey pointed out, and I neglected to read in the link, just using my example as-is will result in an infinite loop. Also using HTTPS should work in place of SERVER_PORT_SECURE.


    Filed under: I don't always Copy-Pasta, but when I do...



  • I didn't write the fucking code. I don't have the version of it I wrote.


Log in to reply