Page MenuHomePhabricator

CORS Preflight fails when request has Access-Control-Request-Method and Access-Control-Request-Headers headers
Closed, ResolvedPublic

Description

If you have a request like this:

curl 'https://meta.wikimedia.org/w/api.php?action=query&format=json&list=users&usprop=blockinfo&origin=*&ususerids=123' -X OPTIONS -H 'access-control-request-method: GET' -H 'origin: http://127.0.0.1:8888' -H 'access-control-request-headers: x-requested-with' --compressed -I

It fails (and by failure, I mean it is missing the Access-Control-Allow-Origin header) because it has both Access-Control-Request-Method and Access-Control-Request-Headers headers (which is included in the preflight request of Chrome and Firefox). If you remove either header, the request will succeed.

Here's the error message in the browser's console:

XMLHttpRequest cannot load https://meta.wikimedia.org/w/api.php?action=query&format=json&list=users&usprop=blockinfo&origin=*&ususerids=123. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8888' is therefore not allowed access.

Event Timeline

ooo! found out the library I was using was adding a X-Requested-With header I removed that and then Access-Control-Request-Headers was removed from preflight which made the request succeed.

So, is this issue a bug? or is it intentional?

The problem is that x-requested-with is not an allowed header. Following the algorithm laid out at https://www.w3.org/TR/cors/#resource-preflight-requests, it therefore terminates at step 6 before setting the CORS response headers. If this header should be allowed in the actual request, feel free to submit a patch adding it to the list of allowed request headers.

When you omit Access-Control-Request-Method, the request is no longer a preflight request. It's probably a bug that the API is treating it as a simple request when simple requests can only be GET, HEAD, and POST.

Change 360687 had a related patch set uploaded (by Anomie; owner: Anomie):
[mediawiki/core@master] API: Don't handle non-preflight OPTIONS as CORS

https://gerrit.wikimedia.org/r/360687

Change 360687 merged by jenkins-bot:
[mediawiki/core@master] API: Don't handle non-preflight OPTIONS as CORS

https://gerrit.wikimedia.org/r/360687

Anomie claimed this task.

A non-preflight OPTIONS request won't be treated as a CORS request anymore, which should reduce confusion, and a response header indicating why a request wasn't treated as CORS will be added to help future debugging of issues like this.