0

So an old program (windows exe) does a request to our site with this header:

"Accept-Charset[space]:ISO-8859-1"

And this throws a 400 Bad Request error. We cannot change that and remove the space (which would solve the nightmare) because that exe is already installed in a ton of computers.

This was not causing any issue when the web was a 20 year old ASP Web Forms, but now, the new NET 6 MVC doesn't like it.

The IAsyncActionFilter filter is not a solution as the BAD Request is returned before the query can even be routed.

Do you have any clue on how to parse that request removing the space or any other magic that can solve this?

Thank you!

  • You might be able to use IIS' _URL Rewriter_ functionality to alter that header too (you can use it for a lot more than just rewriting request-paths, it's a reverse-proxy too). – Dai Aug 10 '22 at 18:09
  • Yes it's that. I need to add a web.config file in my AppService app and the AppService IIS will apply the URL Rewrite. Now I need a magician that help me to tell IIS to ignore bad headers or to replace Accept-Charset: ISO-8859-1" to Accept-Charset: ISO-8859-1". Thank you Dai. – Xavier Casals Aug 13 '22 at 07:21
  • Are you able to run your old WebForms code and use VS's debugger to set a breakpoint when a request has the malformed `Accept-CharSet :`) header? I'm curious if `HttpContext.Request.Headers` shows the trailing space in the header name or not. As for the HTTP 400 error: do you know where/how ASP.NET Core is creating it? – Dai Aug 13 '22 at 08:52
  • Sorry, I'm don't have that code to test ;( And the 400 Bad Request, I cannot debug this error because it's thrown at IIS level, way before I receive the request in ASP.NET. – Xavier Casals Aug 14 '22 at 09:56
  • ...so how did the old ASP.NET code work if it's IIS that rejects the request? – Dai Aug 14 '22 at 10:21
  • That's a good question. Old code was hosted in our own IIS. Now the Web is hosted in Azure App Service. Maybe there are different default filters or whatever. – Xavier Casals Aug 19 '22 at 09:34

2 Answers2

0

I guess you are looking for something called Middleware (msdn).

In short, it gives you access to the request/response pipeline - so you can perform some actions with request before it reaches your controller and with response before it is passed to a client.

Implementation

In your Startup.cs:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        ///           ///
        /// Your code ///
        ///           ///
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        ///           ///
        /// Your code ///
        ///           ///

        app.UseMiddleware<HttpHeadersAligner>();
    }
}

HttpHeadersAligner.cs

public class HttpHeadersAligner
{
    private readonly RequestDelegate _next;
    public HttpHeadersAligner(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        ///
        /// Your code
        /// 
    }
}
laskau
  • 1
  • Thank you for your answer, but that does not solve the problem. The thing brakes before this middleware is activated as IIS cannot parse the request. When I curl my URL and put that space before the colon, the program doesn't even stop there. – Xavier Casals Aug 13 '22 at 07:00
  • curl --header "Accept-Charset: ISO-8859-1" https://localhost:51818/ – Xavier Casals Aug 13 '22 at 07:00
0

Using IIS' URL Rewrite 2.0:

  • NOTE: The OP said their problem is that old client software is sending HTTP requests with a malformed Accept-Charset header (it has a space 0x20) after the Accept-Charset header name but before the colon (and no space after the colon), i.e. "Accept-Charset :ISO-8859-1".

    • I do not know if IIS' URL Rewrite extension will correctly match this header. My answer is written in the assumption that it does. YMMV.
  • You will need version 2.0 (or later) of the IIS URL Rewrite extension to manipulate request and response headers (amongst other things) before ASP.NET Core sees the request.

  • Recommended reading:

  • IIS URL Rewrite 2.0 can edit (add, set, edit, and remove) request and response headers via their HTTP Server Variable representations.

    • Request headers are identified and matched by strings of the form HTTP_{UPPER_SNAKE_CASE_HEADER_NAME}.
    • Response headers are identified by strings of the form RESPONSE_{HEADER_NAME}.
    • For example:
      • Match the Content-Type request header with HTTP_CONTENT_TYPE.
      • Match the Content-Type response header with RESPONSE_Content-Type.
    • In your case, to match Accept-Charset :ISO-8859-1 I assume that IIS will either strip the space by itself and match HTTP_ACCEPT_CHARSET - or - IIS will allow and match a trailing literal space or XML entitized space (&#x20;) as "HTTP_ACCEPT_CHARSET " or "HTTP_ACCEPT_CHARSET&#x20;" respectively.
      • I have not tested this, however.
  • NOTE: In order to allow a <rewrite> configuration to edit HTTP headers, you need to edit IIS' applicationHost.config file (which defines server-level settings and Website configuration) to add the HTTP server variable representation of those request/response header names to the <allowedServerVariables> list.

    • In Azure App Services (aka Azure Websites) you can do this with your applicationHost.xdt file, placed at D:\home\site\applicationHost.xdt - and the file should look like this:
      <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
          <system.webServer>
              <rewrite>
                  <allowedServerVariables>
                       <!-- I'm trying different patterns so that the trailing space will hopefully be matched. -->
                       <add name="HTTP_ACCEPT_CHARSET" xdt:Transform="InsertIfMissing" xdt:Locator="Match(name)" />
                       <add name="HTTP_ACCEPT_CHARSET " xdt:Transform="InsertIfMissing" xdt:Locator="Match(name)" />
                       <add name="HTTP_ACCEPT_CHARSET&#x20;" xdt:Transform="InsertIfMissing" xdt:Locator="Match(name)" />
                   </allowedServerVariables>
               </rewrite>
           </system.webServer>
      </configuration>
      
    • In other hosting scenarios, consult your hosting provider.
  • Here's something that I feel should work...

    • I assume <action type="None" /> will still edit the HTTP request headers, but if not, try <action type="Rewrite" url="{R:0}" /> (which will rewrite the request URL to itself, a NOOP, basically).
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    
    <system.webServer>
        <rewrite>
            <rule name="ClearAcceptCharset0" stopProcessing="true">
                <match url=".*" />
                <conditions>
                    <add input="{HTTP_ACCEPT_CHARSET}" pattern="(.+)" />
                </conditions>
                <serverVariables>
                    <set name="HTTP_ACCEPT_CHARSET" value="" />
                    <set name="HTTP_ACCEPT_CHARSET " value="" />
                    <set name="HTTP_ACCEPT_CHARSET&#x20;" value="" />
                </serverVariables>
                <action type="None" />
            </rule>
            <rule name="ClearAcceptCharset1" stopProcessing="true">
                <match url=".*" />
                <conditions>
                    <add input="{HTTP_ACCEPT_CHARSET }" pattern="(.+)" />
                </conditions>
                <serverVariables>
                    <set name="HTTP_ACCEPT_CHARSET" value="" />
                    <set name="HTTP_ACCEPT_CHARSET " value="" />
                    <set name="HTTP_ACCEPT_CHARSET&#x20;" value="" />
                </serverVariables>
                <action type="None" />
            </rule>
            <rule name="ClearAcceptCharset2" stopProcessing="true">
                <match url=".*" />
                <conditions>
                    <add input="{HTTP_ACCEPT_CHARSET&#x20;}" pattern="(.+)" />
                </conditions>
                <serverVariables>
                    <set name="HTTP_ACCEPT_CHARSET" value="" />
                    <set name="HTTP_ACCEPT_CHARSET " value="" />
                    <set name="HTTP_ACCEPT_CHARSET&#x20;" value="" />
                </serverVariables>
                <action type="None" />
            </rule>
        </rewrite>
    </system.webServer>

</configuration>
  • HTH, YMMV, etc.
Dai
  • 141,631
  • 28
  • 261
  • 374
  • Hi and thank you for your great response. Following the instructions, I connected to the AppService FTP and modified the file found in /SiteExtensions/applicationHost.xdt adding both samples, but no way ;( – Xavier Casals Aug 14 '22 at 10:34