IIS hijacks CORS Preflight OPTIONS request
Asked Answered
A

16

55

I am making a CORS POST request and setting the Content-Type header to json. This triggers a Preflight OPTIONS request to fire (this is good and expected)

This OPTIONS request is responded to with a 200 OK but this isn't coming from my WebAPI application.

I have a custom Message Handler in place and it never get's hit so the request is getting responded to by IIS prior to hitting ASP.NET it seems.

I have found several posts on the subject and they say the following

  1. Make sure WebDav is uninstalled / removed / disabled - DONE

  2. Make sure the OPTIONSVerbHandler is removed / changed to use aspnet_isapi.dll - TRIED BOTH

  3. Make sure the extensionlessURLHandler includes the OPTIONS verb - DONE

However, my options request is still getting hijacked. By that I mean, IIS responds with at 200 OK but isn't including an Access-Control-Allow-Origin header in the response. It isn't including this header because it is never getting to my WebAPI CORS code that would set this header.

The two best posts I could find that sound like my issue are

here: JQuery stuck at CORS preflight and IIS ghost response

and here: http://brockallen.com/2012/10/18/cors-iis-and-webdav/

I have tried turning on Failed Request tracing (FERB) in IIS and set it to trace all 200 status codes. I don't ever see the options request being logged... Not sure if this means FERB doesn't track OPTIONS requests or if I need to change something in the FERB settings to make it track OPTIONS requests, Or if this is a clue to what my problem is?

This is ASP.NET WebAPI 2.0 running on IIS 7.5 (Also tested on IIS 8 and IISExpress with same results) Doesn't matter what browser (Chrome, FF, and IE all fail the same way)

I have tried everything I can find on the subject and still can't fix my problem.

Help me StackOverflow, you're my only hope.

Aeromarine answered 19/3, 2014 at 2:49 Comment(2)
I am facing similar issue, please let me know if you could help #28213710Cherie
Microsoft released IIS CORS module too late learn.microsoft.com/en-us/iis/extensions/cors-module/…Canea
B
32

A couple of things you can try here, all web.config related, firstly modify your modules element to include the attribute runAllManagedModulesForAllRequests="true", as below:

<modules runAllManagedModulesForAllRequests="true">
    <remove name="WebDavModule" />
</modules>

Then set your handlers to the below:

<handlers>
   <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
   <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
   <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
   <remove name="WebDav" />
   <remove name="OPTIONSVerbHandler" />
   <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
   <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
   <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

This should do the trick, but if it doesn't, as a last resort you can force IIS to output the correct headers with the below:

  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" />
        <add name="Access-Control-Allow-Headers" value="Content-Type" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>

Be wary of the wildcard value, you should really set this to the domain name that your site will be hosted on.

Basket answered 19/3, 2014 at 4:6 Comment(9)
Hi Tom, I tried the first solution, still didn't fix the problem. The second solution is my current "fix" but this isn't a fix at all. It is a hack and breaks my CORS rules. Since I now have to allow origin *, which isn't what I want. I have multiple consuming sites I need to trust, so * doesn't work and a single site doesn't work either.Aeromarine
Absolutely, it's a hack and isn't at all ideal. I've run into the issue myself and actually got it working, I'm pretty sure it was to do with handler mappings, setting the path and verb attribute, see my updated answer. Let me know if it works.Basket
Thanks for the update. I have tried these settings with no luck. It all is "supposed" to work with what I have but something is still not right. Maybe the question is more "How can I figure out what is responding to this request in IIS"?Aeromarine
It's a bit mystic isn't it. I've just done some further reading and found one snippet which could be helpful, add <remove name="OPTIONSVerbHandler"/> to the <handlers/> section.Basket
Yup tried that too.. I have seen people saying, remove it and some people saying remap it. I tried both and still no luck. Thanks for the suggestions so far. I am sure there is a solution out there but I haven't found it.Aeromarine
What version of IIS are you using? Apparently OPTIONSVerbHandler works for v7.5 and below, for 8.0 onwards it's just OPTIONSBasket
I am on 7.5. I think I need to move this to a new question about how to get FERB to capture the options request so I can figure out what module is responding to itAeromarine
I use the second one and i got "Response to preflight request doesn't pass access control check: It does not have HTTP ok status." Can you please advise? ThanksHaitian
Tried many things, then found this answer, removed the WebDav module from the modules list inside iis and it immediately worked, even without iis restart.Oviposit
A
11

that's what worked for me after 4 hours of searching/experimenting:

    <handlers>
        <remove name="OPTIONSVerbHandler" />
        <add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="IsapiModule" scriptProcessor="C:\Windows\System32\inetsrv\asp.dll" resourceType="Unspecified" requireAccess="None" />
    </handlers>
Africa answered 3/11, 2016 at 23:35 Comment(3)
What IIS version are you using?Chard
IIS 7.5 on Windows Server 2008R2 SP1, ASP classicAfrica
Worked with this: <add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="None" />Yajairayajurveda
D
7

I tried all of the above suggestions as well as others I found on SO and what mattered in my situation was we had Request Filtering enabled on IIS and the OPTIONS HTTP Verb was not in the list of allowed verbs. Once I added it I was able to sort out the rest of it.

Dermal answered 17/9, 2015 at 17:4 Comment(3)
Where did you add it?Strumpet
In IIS on the server, select the site and there is an option in the list of features called Request Filtering. Then go to the HTTP Verbs tab and on the right under Actions select Allow Verb and type in 'OPTIONS' and click ok.Midmost
This was it for me too. There was nothing in the Events or logs anywhere - the request just 404'd. Funny...it worked without this step on another instance of IIS which did not have this on by default.Microfilm
L
6

I had the same issue and the following web.config settings fixed it for me.

    <modules runAllManagedModulesForAllRequests="false">
      <remove name="FormsAuthenticationModule" />
    </modules>
    <handlers>
      <remove name="OPTIONSVerbHandler" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>

I was then able to handle CORS OPTIONS requests manually in Application_BeginRequest.

I was originally using the library detailed in this blog post for handling CORS requests. The product I'm working on requires that runAllManagedModulesForAllRequests be set to false, though. This is why I had to set up a custom implementation, but if you don't have that requirement you should give that library a try. It worked great when I was able to have runAllManagedModulesForAllRequests set to true.

Liquefacient answered 28/3, 2014 at 2:17 Comment(2)
Yeah I am already using Thinktecture. I have the opposite requirement, I have to have runAllManageModulesForAllRequests=true. Removing the FormsAuthModule is interesting, I don't use it so I am going to try and remove it, though I would be surprised if that fixed it.Aeromarine
Strange you're having this issue using the Thinktecture library. I didn't need to make any changes to handlers when I was using it.Liquefacient
P
5

In our case it was request filtering in IIS disabling OPTIONS verb at the root web application level. Open up IIS Manager, click on root application, click on Request Filtering, if OPTIONS appears in list either remove or Allow Verb. Wish I had checked this first as lots of wasted time.

Persian answered 16/2, 2017 at 15:13 Comment(1)
Good sir, you have prevented me from smashing my laptop, monitor, and web server into millions of tiny pieces. If I could up vote this a gazillion times, I would. Thank you!Aras
N
1

In my case, I missed the Microsoft.WebApi.Cors package. Installed this package and configured it like so in the WebApiConfig class:

 public static void Register(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();
            config.EnableCors(new EnableCorsAttribute("*","*","*"));
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }

Please fine-tune this before using in production because you probably don't want to have wild-cards for everything

Northwards answered 23/10, 2018 at 7:50 Comment(1)
exactly what i was looking for.Pointing
G
1

This is what worked for me:

  <system.webServer>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>
Gracia answered 6/2, 2019 at 5:36 Comment(0)
I
1

Check if URLScan tool is installed on IIS. When so check following section:


;
; The verbs (aka HTTP methods) listed here are those commonly
; processed by a typical IIS server.
;
; Note that these entries are effective if "UseAllowVerbs=1"
; is set in the [Options] section above.
;

GET
HEAD
POST
OPTIONS
Increase answered 9/10, 2019 at 9:11 Comment(0)
N
0

I know this is an old post, but I just went through the exact same problem.

In my situation, I have CORS installed for both OWIN and WebAPI. The OWIN CORS middleware was intercepting the OPTIONS call long before it ever made it to the WebAPI stuff. Maybe this well help someone else in the future.

Natation answered 4/4, 2015 at 23:13 Comment(2)
Yes and, what did you do about that?Strumpet
What I was implying (not very well apparently) is that you have to add CORS to both the Owin Middleware, and to the WebApi pipeline. Doing one or the other was not sufficient in my case. Also, you may need to re-order the CORS middleware. For example, if you have authentication middleware before your CORS middleware, the call could be rejected straight away because the OPTIONS call will fail since something is trying to handle the request before the CORS process.Natation
L
0

I have installed Microsoft.AspNet.WebApi.Cors & Microsoft.Owin.Cors for my oWin based WebAPI and added app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); at config like below:

public class Startup : IStartup, IAppStartup
{
    public void Configuration(IAppBuilder app)
    {
        var config = this.GetInjectionConfiguration();
        BootstrapperWebApi bootstrapperWebApi = (BootstrapperWebApi)this.GetBootstrapperWebApi(config);

        bootstrapperWebApi.Initialize(true)
        .EnableLogging()
        .DisableWebApiDefaultExceptionHandler();

        WebApiConfig.Register(config);

        app.UseOwinExceptionHandler();

        app.Use<LoggerMiddleware>();

        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        //others stuff

    }
Ludovico answered 25/9, 2017 at 5:57 Comment(0)
B
0

I tried all the mentioned posts but nothing worked for me, then i shifted my ASP.Net Web API 2 service to windows server 2012 (IIS 8.5) and same service worked without any changes. So issue was specific to IIS 7.5 on windows 7 machine.

Boothman answered 9/3, 2018 at 17:21 Comment(0)
M
0

In my case I did this:

    <verbs allowUnlisted="true" applyToWebDAV="true">
      <remove verb="OPTIONS"/>
      <add verb="OPTIONS" allowed="true"/>
    </verbs>
  </requestFiltering>
</security>

When I added <add verb="OPTIONS" allowed="true"/> to the web.config, the application failed to start with this error

HTTP Error 500.19 - Internal Server Error
The requested page cannot be accessed because the related configuration data for the page is invalid.

Cannot add duplicate collection entry of type 'add' with unique key attribute 'verb' set to 'OPTIONS'

So I had to remove it first.

Matriarchy answered 1/4, 2019 at 21:27 Comment(0)
S
0

I have the same issue. The OPTIONS request return 200 OK status but it does not contain Access-Control-Allow-Origin header. The problem was our customer network policy blocking the OPTIONS verb request and response the warning message with 200 OK status. I know this is the old post but I want to share my case for anyone needed.

Schoenburg answered 10/3, 2021 at 2:2 Comment(0)
A
0

One more case, maybe it will save time for somebody. When I used config with HttpConfiguration.EnableCors all was working fine but when I used web.config file it was failing with CORS errors. It started work after I removed the .vs folder.

Aida answered 24/12, 2021 at 8:8 Comment(1)
Your answer is UnclearArvid
D
0

For me with IIS 10 and PHP 8.0 none of the other response worked, it was just the php-cgi handler verb restrictions. because the default php-cgi verbs were POST,GET, HEAD. I fixed it this way:

 <handlers>
            <remove name="PHP_via_FastCGI" />            
            <add name="PHP_via_FastCGI" path="*.php" verb="*" modules="FastCgiModule" scriptProcessor="C:\Program Files\iis express\PHP\v8.0\php-cgi.exe" resourceType="Either" requireAccess="Script" />        
    </handlers>
Dictatorship answered 28/6, 2023 at 5:35 Comment(0)
C
-1

<figure>
  <img src="https://i.sstatic.net/CbRyM.png" alt="">
  <figcaption> change the OptionsVerbHangle</figcaption>
</figure>

<figure>
  <img src="https://i.sstatic.net/wjcMV.png" alt="Minha Figura">
  <figcaption>Adicione * and in the case of php use fastcgimodule</figcaption>
</figure>

<figure>
  <img src="https://i.sstatic.net/wRwpi.png" alt="Minha Figura">
  <figcaption>Mapping to folder
 </figcaption>
</figure>

<figure>
  <img src="https://i.sstatic.net/hhqJi.png" alt="Minha Figura">
  <figcaption>all verbs
 </figcaption>
</figure>

<figure>
  <img src="https://i.sstatic.net/86kKX.png" alt="Minha Figura">
  <figcaption>Select script
 </figcaption>
</figure>

Just follow the images below to unlock the colors in IIS

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

Calvados answered 27/12, 2021 at 21:3 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Lattimer

© 2022 - 2024 — McMap. All rights reserved.