tyoshino / origin-wide-cors

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Origin-Wide CORS

Editor: Takeshi Yoshino

Introduction

Extra round trip caused by CORS preflight has been adding significant delay to XHR/Fetch with non-simple headers/method. This is preventing performance sensitive applications from adopting web platform.

The Origin-Wide CORS mechanism improves this by allowing an origin server to announce CORS capability and parameters widely across resources.

Design points

Starting with just summarizing ideas proposed at whatwg/fetch#210

Plans

  • Start with just allowing for announcing that the origin understands CORS and therefore it's safe to omit preflight. And then, extend it to enable announcing capability in more fine-grained form and detailed parameters
  • Have almost the same level of cumbersomeness as current preflight to prevent people from copy&pasting

Strawman

  • On the initial cross-origin non-simple request to an origin X from origin Y

    • The client A issues a preflight request to resource R
      • The preflight request MAY include Origin-Wide-CORS-Supported: yes header to announce it understands Origin-Wide CORS protocol
    • If a server B sees the Origin-Wide-CORS-Supported header entry in the received CORS preflight or actual CORS request, it MAY include the Origin-Wide-CORS header whose value is a Origin-Wide CORS descriptor
      • The Origin-Wide-CORS-Supported header must have either a value yes or version parameter or tag parameter
      • Any entry in the Origin-Wide CORS descriptor whose url field is pointing at a resource which is not under R, it must be ignored.
  • On the initial request to a ...

Origin-Wide-CORS header

The Origin-Wide-CORS header has a JSON formatted value quoted by quoted-string if needed.

{
  "cors": [
    {
      "url": "/service",
      "origin": "http://www.example.com",
      "max-age": 31536000,
      "credentials": false,
      "method": "get",
      "headernames": ["x-requested-with", "custom"]
    },
    ...
  ],
  "csp": ...
  "upgrade-insecure-requests": ...
}
  • This parameter will be stored into the CORS preflight cache with the origin-wide-cors flag
    • Pathes such as "/service", "/service/x", "/service/x/y", "/service/x/y?z=foo", etc. are requested, this cache will be instantiated to a CORS preflight cache entry without the origin-wide-cors flag (creates entries for each headername in headernames)
      • matching is done from the first entry to the last entry
      • Partial update is not supported
      • The instantiation doesn't happen if there's existing active entry
    • Pathes such as "/servicex", "/servicex/y", etc. are not affected.
  • Note: origin field doesn't support the wildcard "*". A concrete origin must be specified.
  • credentials defaults to false meaning that this Origin-Wide-CORS parameters affects only non-credentialled requests
  • The only allowed value for credentials is false for the initial version of the protocol
  • An Origin-Wide-CORS descriptor fetched over HTTP is not applicable to fetches over HTTPS
  • An Origin-Wide-CORS descriptor fetched over HTTPS is applicable to fetches over both HTTPS and HTTP

Issues

  • The descriptor gets cached together with the resource R? Separately maintained?

    • -> only in response to OPTIONS?
  • Only root considering security concerns?

General Origin-Wide Policy

This protocol can be generalized to allow for announcing various policies in addition to the CORS.

Alternatives

  • Standardize how to embed non-simple headers in a URL
  • Foreign fetch ServiceWorker

References

Acknowledgement

Thanks to Ben Kelly, bifurcation, Jonas Sicking, roryhewitt, Mark Nottingham, Wenbo Zhu.

About