Page MenuHomePhabricator

Add `Access-Control-Max-Age` to `$wgAllowedCorsHeaders`
Closed, ResolvedPublic

Description

Mediawiki core should allow the Access-Control-Max-Age header in Cross-origin resource sharing (CORS) api requests.

Use case: T268267: Reduce CORS preflight requests - cache the result of OPTIONS api calls to avoid needing to make a new CORS preflight request before each api call to each wiki.

Tagging Security-Team per @Legoktm's suggestion at T268267#6674947 - is this okay from a security perspective?

See also:

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript

Change 646768 had a related patch set uploaded (by DannyS712; owner: DannyS712):
[mediawiki/core@master] Add Access-Control-Max-Age to $wgAllowedCorsHeaders

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

@DannyS712 - the patch above seems to just add Access-Control-Max-Age to the allow list for Access-Control-Request-Headers requests, no? It actually wouldn't be implemented in ApiMain.php (or wherever) until someone writes that code, correct? In which case, we'd definitely want to be careful about cache time defaults (especially in Firefox). Let me know if I've missed something here.

@DannyS712 - the patch above seems to just add Access-Control-Max-Age to the allow list for Access-Control-Request-Headers requests, no?

Yes

It actually wouldn't be implemented in ApiMain.php (or wherever) until someone writes that code, correct? In which case, we'd definitely want to be careful about cache time defaults (especially in Firefox). Let me know if I've missed something here.

If I understand correctly, ApiMain just validates the list of requested headers in OPTIONS requests and would now allow this header, but we aren't changing anything with defaults, etc. - previously, if this header was requested the api call would fail, now it won't, and its up to the caller to add the header and add caching - no defaults are being changed as far as I know.

If I understand correctly, ApiMain just validates the list of requested headers in OPTIONS requests and would now allow this header, but we aren't changing anything with defaults, etc. - previously, if this header was requested the api call would fail, now it won't, and its up to the caller to add the header and add caching - no defaults are being changed as far as I know.

That's my understanding as well, so this should be a pretty benign change for now, until further implementation occurs, in that users are just requesting a CORS header that won't be sent for the time being. And again, down the road, we'd want to be cautious of allowed cache max ages (and certainly that shouldn't be anything users would be allowed to configure or set in any way).

sbassett removed a project: Security-Team.

If I understand correctly, ApiMain just validates the list of requested headers in OPTIONS requests and would now allow this header, but we aren't changing anything with defaults, etc. - previously, if this header was requested the api call would fail, now it won't, and its up to the caller to add the header and add caching - no defaults are being changed as far as I know.

That's my understanding as well, so this should be a pretty benign change for now, until further implementation occurs, in that users are just requesting a CORS header that won't be sent for the time being. And again, down the road, we'd want to be cautious of allowed cache max ages (and certainly that shouldn't be anything users would be allowed to configure or set in any way).

Okay, I've removed my -2 on the patch accordingly. For the immediate use case of T268267: Reduce CORS preflight requests I was going to set it to cache for 5 minutes (and not subject to user configuration) - would that be okay?

Okay, I've removed my -2 on the patch accordingly. For the immediate use case of T268267: Reduce CORS preflight requests I was going to set it to cache for 5 minutes (and not subject to user configuration) - would that be okay?

For the least amount of risk, it should be as low as possible while still offering reasonable performance gains. The browser defaults, according to https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age#Directives are:

  • Firefox: 24 hours (86400 seconds).
  • Chromium (prior to v76): 10 minutes (600 seconds).
  • Chromium (starting in v76): 2 hours (7200 seconds).
  • Chromium also specifies a default value of 5 seconds.

As a first pass, single-digit minute durations seem reasonable, given the above. I certainly don't think we'd ever want to push past 10 minutes, unless there were significant performance issues which might elicit a need for compromise.

Change 646768 merged by jenkins-bot:
[mediawiki/core@master] Add Access-Control-Max-Age to $wgAllowedCorsHeaders

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

DannyS712 claimed this task.

Change 651707 had a related patch set uploaded (by DannyS712; owner: DannyS712):
[mediawiki/core@master] RELEASE-NOTES document cors support for Access-Control-Max-Age

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

Change 651707 merged by jenkins-bot:
[mediawiki/core@master] RELEASE-NOTES: Document CORS support for Access-Control-Max-Age

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

Change 921158 had a related patch set uploaded (by Reedy; author: DannyS712):

[mediawiki/core@REL1_35] Add `Access-Control-Max-Age` to `$wgAllowedCorsHeaders`

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

Change 921158 merged by jenkins-bot:

[mediawiki/core@REL1_35] Add `Access-Control-Max-Age` to `$wgAllowedCorsHeaders`

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