Skip to content

IIS: % in URL is double-unescaped #41168

@mus65

Description

@mus65

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

We have a method with the template "api/{id}" where id is a string. So when we want to pass the literal "%abc", the encoded url is api/%25abc .

By default, IIS will reject this with status 404.11 due to security reasons. We have to set the following in web.config for IIS to allow this:

<system.webServer>
    <security>
      <requestFiltering allowDoubleEscaping="true" />
    </security>
</system.webServer>

The issue is that while this works with the example string "%abc", other values break or even cause internal exceptions due to ASP .NET Core unescaping the already unescaped URL. For example calling "api/%2542" which should result in id being the literal "%42" instead results in "B".

The URL api/%2500" even causes the following exception because 00 is unescaped to a null-byte.

Microsoft.AspNetCore.Server.IIS.Core.IISHttpServer: Error: Connection ID "17654110548687585306", Request ID "4000001b-0002-f500-b63f-84710c7967bb": An unhandled exception was thrown by the application.

System.InvalidOperationException: The path contains null characters.
   at Microsoft.AspNetCore.Internal.UrlDecoder.DecodeCore(Int32& sourceIndex, Int32& destinationIndex, Span`1 buffer)
   at Microsoft.AspNetCore.Internal.UrlDecoder.DecodeInPlace(Span`1 buffer)
   at Microsoft.AspNetCore.Http.PathString.FromUriComponent(String uriComponent)
   at Microsoft.AspNetCore.Builder.Extensions.UsePathBaseMiddleware.InvokeCore(HttpContext context, String matchedPath, String remainingPath)
   at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT`1.ProcessRequestAsync()

This is with Windows 11 and the latest .NET Hosting Bundle 6.0.4. I can't reproduce this with IIS Express. #30655 may be related, but it does not seem to be specific to IIS.

Expected Behavior

Value from URL is unescaped correctly.

Steps To Reproduce

Define the following method:

[HttpGet("test/{id}")]
public ActionResult Get(string id)
{
  return Ok(id);
}

Start the application in IIS (not IIS Express).

Calling the URL "test/%2500" will cause the mentioned internal exception. Calling "test/%2542" will return "B".

Exceptions (if any)

Microsoft.AspNetCore.Server.IIS.Core.IISHttpServer: Error: Connection ID "17654110548687585306", Request ID "4000001b-0002-f500-b63f-84710c7967bb": An unhandled exception was thrown by the application.

System.InvalidOperationException: The path contains null characters.
   at Microsoft.AspNetCore.Internal.UrlDecoder.DecodeCore(Int32& sourceIndex, Int32& destinationIndex, Span`1 buffer)
   at Microsoft.AspNetCore.Internal.UrlDecoder.DecodeInPlace(Span`1 buffer)
   at Microsoft.AspNetCore.Http.PathString.FromUriComponent(String uriComponent)
   at Microsoft.AspNetCore.Builder.Extensions.UsePathBaseMiddleware.InvokeCore(HttpContext context, String matchedPath, String remainingPath)
   at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT`1.ProcessRequestAsync()

.NET Version

6.0.4

Anything else?

No response

Metadata

Metadata

Assignees

Labels

area-networkingIncludes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions