Page MenuHomePhabricator

Cannot do CORS request with valid origin on Wikidata
Open, Needs TriagePublicBUG REPORT

Description

I am trying to make an OAuth2-authenticated request on Wikidata from an SPA on a localhost web client. However, I keep on running into CORS errors, and I double-checked the origin to make sure I am doing it right. I copied the request into cURL and found something interesting:

*   Trying 2620:0:861:ed1a::1:443...
* Connected to www.wikidata.org (2620:0:861:ed1a::1) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=*.wikipedia.org
*  start date: Oct 26 08:25:13 2022 GMT
*  expire date: Jan 24 08:25:12 2023 GMT
*  subjectAltName: host "www.wikidata.org" matched cert's "*.wikidata.org"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x156011400)
> GET /w/api.php?action=query&format=json&meta=tokens&formatversion=2&origin=http%3A%2F%2Flocalhost%3A16000 HTTP/2
> Host: www.wikidata.org
> accept: */*
> accept-encoding: deflate, gzip
> sec-ch-ua: "Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"
> dnt: 1
> sec-ch-ua-mobile: ?0
> user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
> authorization: Bearer <token expunged, but it is valid>
> origin: http://localhost:16000
> referer: http://localhost:16000/
> api-user-agent: Animanga DB Matcher (User:RPI2026F1)
> sec-ch-ua-platform: "macOS"
>
< HTTP/2 200
< date: Tue, 22 Nov 2022 14:54:50 GMT
< server: mw1363.eqiad.wmnet
< x-content-type-options: nosniff
< mediawiki-cors-rejection: Origin mismatch
< x-frame-options: DENY
< content-disposition: inline; filename=api-result.json
< cache-control: private, must-revalidate, max-age=0
< vary: Accept-Encoding
< content-length: 101
< content-type: application/json; charset=utf-8
< age: 2
< x-cache: cp1087 pass, cp1089 pass
< x-cache-status: pass
< server-timing: cache;desc="pass", host;desc="cp1089"
< strict-transport-security: max-age=106384710; includeSubDomains; preload
< report-to: { "group": "wm_nel", "max_age": 86400, "endpoints": [{ "url": "https://intake-logging.wikimedia.org/v1/events?stream=w3c.reportingapi.network_error&schema_uri=/w3c/reportingapi/network_error/1.0.0" }] }
< nel: { "report_to": "wm_nel", "max_age": 86400, "failure_fraction": 0.05, "success_fraction": 0.0}
< set-cookie: WMF-Last-Access=22-Nov-2022;Path=/;HttpOnly;secure;Expires=Sat, 24 Dec 2022 12:00:00 GMT
< set-cookie: WMF-Last-Access-Global=22-Nov-2022;Path=/;Domain=.wikidata.org;HttpOnly;secure;Expires=Sat, 24 Dec 2022 12:00:00 GMT
< accept-ch: Sec-CH-UA-Arch,Sec-CH-UA-Bitness,Sec-CH-UA-Full-Version-List,Sec-CH-UA-Model,Sec-CH-UA-Platform-Version
< permissions-policy: interest-cohort=(),ch-ua-arch=(self "intake-analytics.wikimedia.org"),ch-ua-bitness=(self "intake-analytics.wikimedia.org"),ch-ua-full-version-list=(self "intake-analytics.wikimedia.org"),ch-ua-model=(self "intake-analytics.wikimedia.org"),ch-ua-platform-version=(self "intake-analytics.wikimedia.org")
< x-client-ip: 2620:0:2820:2001:a4fe:420d:269d:3967
< set-cookie: GeoIP=<GeoIP expunged>:v4; Path=/; secure; Domain=.wikidata.org
< accept-ranges: bytes
<
* Connection #0 to host www.wikidata.org left intact
{"batchcomplete":true,"query":{"tokens":{"csrftoken":"3706a9e3b8cdcd587567a563959d2642637ce2bb+\\"}}}

I am getting valid data but a complete lack of any CORS headers, so my browser is unable to do the request.

Event Timeline

I had to add these headers with a browser plugin:

access-control-allow-credentials: true
access-control-allow-headers: *
access-control-allow-methods: PUT, GET, HEAD, POST, DELETE, OPTIONS
access-control-allow-origin: http://localhost:16000

I do think that the allow methods could be simplified to GET, POST, OPTIONS though. I am not sure what headers should be allowed though, so I just whitelisted all of them.

Have you tried setting the origin URL parameter to * instead? (I don’t know if the Authorization header still works in that case, but that should at least send CORS headers.)

It works for unauthenticated requests. My problem is that I need to be able to make authenticated requests since the tool writes information back to Wikidata.

Yes, I was hoping that origin=* might still support authenticated requests with an Authorization header. But it looks like it doesn’t work: $AllowedCorsHeaders doesn’t include Authorization by default; and even if I added it locally, the request still ends up as anonymous.

If that is the case, then MW isn't even looking at the Authorization header is origin=*,