Closed shaliko closed 6 years ago
Interesting
@phanimahesh could you describe here what you shared on the chat about CORS, preflight, etc.? That way we have a public record for any developer who takes this task.
@bajiat please consider cross-posting your questions from chat to this issue, so we can have a record of the discussion in the issue thread. That way we don't need to dig through chat logs to find key information, decisions, etc. related to this issue.
Everything below is either paraphrasing the above documents or my personal interpretation.
[MDN]
A resource makes a cross-origin HTTP request when it requests a resource from a different domain, protocol, or port to its own.
For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts.
The Cross-Origin Resource Sharing (CORS) mechanism gives web servers cross-domain access controls, which enable secure cross-domain data transfers.
Some requests are sent normally. An exhaustive list of conditions for this is present at [MDN] Simple Requests. As a rule of thumb, if the request is possibly using a html <form>
element and no javascript, it will be sent directly.
Every request not covered by the above exceptions is considered potentially dangerous, and will cause a separate "preflight" request to be sent to verify if the request can be sent safely.
[Fetch] Section 3.2.2
A CORS-preflight request is a CORS request that checks to see if the CORS protocol is understood. It uses
OPTIONS
as method and includes these headers:
Access-Control-Request-Method
Indicates which method a future CORS request to the same resource might use.Access-Control-Request-Headers
Indicates which headers a future CORS request to the same resource might use.
Servers that wish to allow websites/applications on other origins to access their apis must respond to preflight requests indicating the same.
[MDN] Preflighted requests and redirects
Most browsers currently don’t support following redirects for preflighted requests.
The following headers must be present in the response to preflight requests (those made with OPTIONS
method).
Access-Control-Allow-Origin
with a comma separated list of allowed origins, or the special wildcard *
meaning all origins.Access-Control-Allow-Methods
with a comma separated list of HTTP methods that are allowed to be sent.Access-Control-Allow-Headers
with a comma separated list of headers that are allowed to be sent. A safelist of allowed headers need not be specified. The safelist contains the same headers that won't trigger a preflight request.Access-Control-Allow-Credentials
with true
/false
indicating if cookies and other authentication information can be sent.The actual request is blocked if preflight response does not allow it. If credentials are allowed just *
in origin is not acceptable. The exact requesting origin must be present in the allowed origins.
Cross origin responses are not readable unless explicitly allowed. The response headers must contain:
Access-Control-Allow-Credentials: true
if the request included credentials.Access-Control-Allow-Origin
with either *
or the origin of the request if reading the response body should be allowedAccess-Control-Expose-Headers
with a list of headers that are allowed to be accessedAPI keys are sent usually as Bearer
tokens by sending a header Authorization: Bearer <api-key>
. Since this header is not in the whitelist for simple requests, this will trigger a preflight request.
Either the API proxy or the API backend servers must respond with the preflight response headers to an OPTIONS
request. Preflight responses must contain Access-Control-Allow-Origin
, Access-Control-Allow-Methods
, Access-Control-Allow-Headers
. A-C-A-Headers must include Authorization
.
Neither the specification nor any other documents I read so far explicitly state if Authorization
headers are considered credentials, and the wording is ambiguous (at least to me). This is relevant to decide
Access-Control-Allow-Origin: *
is acceptable in preflight response or if exact origin must be specified.Access-Control-Allow-Credentials: true
must be present in all responses.
I recommend some experimentation to verify the behaviour of all major browsers, unless we find an authoritative source clarifying this.All API responses must contain Access-Control-Allow-Origin
and optionally Access-Control-Expose-Headers
.
@mauriciovieira can you please estimate this task?
nooooooooo
As Apinf user, I want able create requests from swagger UI to original API without Access-Control-Allow-Origin header. So we need set "Access-Control-Allow-Origin: *" response header on proxy when creating new API backend.
Goal:
Also, recommendation checks other useful security headers (separate task/research):
/cc @marla-singer