3

I've been trying to restrict backslashes \ in URL's via the Request filtering tool in IIS 7 by using:

  <configuration>
   <system.webServer>
      <security>
         <requestFiltering>
            <denyUrlSequences>
               <add sequence="\" />
            </denyUrlSequences>
         </requestFiltering>
      </security>
   </system.webServer>
</configuration>

However, the backslash rule is being completely ignored? Request filtering is definitely working as I've tried with strings instead of a backslash e.g. contact-us as a deny rule correctly sends you to a 404 page. But why is it ignoring the backslash? Is there something missing here?

Thankyou for your help

Duane
  • 131
  • 1
  • 3

1 Answers1

5

I looked at a similar problem recently and found that backslashes were being replaced with forward slashes by HTTP.sys before the requests were handed off to IIS. So, the Request Filtering module will never get a chance to block the request because it won't see the backslashes.

In more detail, I sent the following request

$ wget "http://www.example.com/awesome-category\awesome-products/"
--2012-08-22 12:51:31-- hhttp://www.example.com/awesome-category%5Cawesome-products/
Resolving www.example.com... 192.168.1.77
Connecting to www.example.com|192.168.1.77|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 56398 (55K) [text/html]
Saving to: `index.html'

2012-08-22 12:51:38 (6.60 MB/s) - `index.html'

And the following showed up in Wireshark:

4 0.001242000 192.168.200.42 192.168.100.177 HTTP 246 GET /awesome-category%5Cawesome-products/ HTTP/1.0

I also set up HTTP.sys event tracing to see what was happening before HTTP.sys handed the request off to IIS & .NET.

It showed the URL as being without a backslash:

<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
    <System>
        <Provider Name="Microsoft-Windows-HttpService" Guid="{dd5ef90a-6398-47a4-ad34-4dcecdef795f}" />
        <EventID>2</EventID>
        <Version>0</Version>
        <Level>4</Level>
        <Task>1</Task>
        <Opcode>12</Opcode>
        <Keywords>0x8000000000000002</Keywords>
        <TimeCreated SystemTime="2012-08-22T11:51:29.179726800Z" />
        <Correlation ActivityID="{80000663-0000-5d00-b63f-84710c7967bb}" />
        <Execution ProcessID="4" ThreadID="1912" ProcessorID="0" KernelTime="8820" UserTime="0" />
        <Channel>Microsoft-Windows-HttpService/Trace</Channel>
        <Computer />
    </System>
    <EventData>
        <Data Name="RequestObj">0xFFFFFA801C33B530</Data>
        <Data Name="HttpVerb">       4</Data>
        <Data Name="Url">http://www.example.com.com:80/awesome-category/awesome-products</Data>
    </EventData>
    <RenderingInfo Culture="en-GB">
        <Level>Information </Level>
        <Opcode>Parse </Opcode>
        <Keywords>
            <Keyword>Flagged on all HTTP events dealing with request processing </Keyword>
        </Keywords>
        <Task>HTTP Request Trace Task </Task>
        <Message>Parsed request (request pointer 0xFFFFFA801C33B530, method 4) with URI http://www.example.com.com:80/awesome-category/awesome-products. </Message>
        <Channel>HTTP Service Channel </Channel>
        <Provider>Microsoft-Windows-HttpService </Provider>
    </RenderingInfo>
</Event>

As far as I can tell HTTP.sys is sanitizing the backslashes in the URL by replacing them with forward slashes. This behavior was documented for IIS 6 here:

The normalization is different when directory traversal is used. For example, the following request is received:

http://www.example.com/RootTest/SubDir1\SubDir2/../../SubDir5/SubDir6

Http.sys normalizes this URL as the following URL:

http://www.example.com/RootTest/SubDir5/SubDir6

Note: The backslash is changed to a forward slash.".

It's also mentioned more recently here:

Any ‘\’ (backslashes) in a URI sent to IIS/WAS are automatically converted to a ‘/’ (forward slash). If a relative address is added that contains a ‘\’ and you send IIS a URI that uses the relative address, the backslash is converted to a forward slash and IIS cannot match it to the relative address. IIS sends out trace information that indicates that there are no matches found.

I got the same behavior on another server, so I suspect there's no way to do this with Request Filtering, in contrast to some of the documentation on iis.net. It would be great to get clearer confirmation from someone at MS, but I couldn't find anything.

Edit: Some of the above is either obsolete, incomplete, or inaccurate. See this answer for an example of rewriting a URL that contains backslashes.

James Lupolt
  • 644
  • 1
  • 7
  • 18
  • Great post! Thanks for taking the time to respond. So if HTTP.sys is catching the backslash and 'fixing' the url before it's handed to IIS/.Net then how do websites, like amazon for example, catch backslashes in URL's and redirect to a 404 page? e.g. http://www.amazon.co.uk/gp/product/B005890FUI/ref=s9_pop_gw_g349_ir06\279-6435419-6960969?pf_rd_m=A3P5ROKL5A1OLE&pf_rd_s=center-2&pf_rd_r=1PYVAJ4C4KKS8049F91A&pf_rd_t=101&pf_rd_p=317827967&pf_rd_i=468294 – Duane Aug 29 '12 at 08:36
  • For some reason, this only sends you to a 404 page in firefox, but request the same url in chrome and it will just fix the backslash and send you to the product page. What i'm trying to achieve is to catch the backslash in the URL, not fix it, and send the user to a 404 error page. If HTTP.sys is sanitizing the URL as you suspect, how is something like this even possible? – Duane Aug 29 '12 at 08:36
  • I'd be surprised if amazon.co.uk is running on Windows, so HTTP.sys probably isn't involved. I don't think what you want to do is possible on IIS unless there is some obscure or undocumented workaround. Are you trying to filter out backslashes for security reasons, like preventing sequences like '\..' in URLs? – James Lupolt Aug 29 '12 at 12:34
  • I guess you could stick a proxy in front of IIS and let it send 404s back. : ) – James Lupolt Aug 29 '12 at 12:46
  • 1
    This is not true. It definitely possible to rewrite url with backslash in IIS – Shrike Mar 23 '17 at 11:38
  • 1
    Here' an issue I encountered recently with "\" being replaced by "/": http://stackoverflow.com/questions/42935514/asp-net-4-webapi-route-with-back-slash/42975180 – Shrike Mar 23 '17 at 14:35