elastic / kibana

Your window into the Elastic Stack
https://www.elastic.co/products/kibana
Other
19.72k stars 8.14k forks source link

Improve CORS response headers #94024

Open jportner opened 3 years ago

jportner commented 3 years ago

With the Kibana 7.11.0 release, we added more granular support for CORS settings, so users can control the Access-Control-Allow-Origin and Access-Control-Allow-Credentials response headers (#84316).

The W3C CORS for Developers guide contains advice for resource owners that we should follow. It's worth noting that Kibana relies on HAPI to set all of its CORS response headers.

7.1. Always send * for resources that respond uniformly

Hapi blindly reflects the specified origin in the Access-Control-Allow-Origin response header.

We should change this so that * is used for static resources.

7.2. Use Vary

Hapi never uses the Vary response header.

We should change this so that Vary is used for dynamic resources.

7.4. Avoid returning Access-Control-Allow-Origin: "null"

Hapi blindly reflects the null origin in the Access-Control-Allow-Origin response header.

It appears that the null origin is never valid, so we should change this so it results in an error instead of a valid CORS response.

Note: Kibana is not vulnerable to the attack described in the link, as we do not server.cors.credentials: true to be set in conjunction with server.cors.origin: * (you must specify individual origins to allow CORS credentials).

elasticmachine commented 3 years ago

Pinging @elastic/kibana-core (Team:Core)

elasticmachine commented 3 years ago

Pinging @elastic/kibana-security (Team:Security)

jportner commented 3 years ago

RE: Origin null:

I am proposing that we return a CORS error to the preflight request.

Here's an example of a CORS success response from Kibana:

% curl -H "Origin: example.com" \
 -H "Access-Control-Request-Method: GET" \
 -X OPTIONS --verbose https://black-box.local:5601/

...

< HTTP/1.1 204 No Content
< access-control-allow-origin: example.com
< access-control-allow-methods: GET
< access-control-allow-headers: Accept,Authorization,Content-Type,If-None-Match,kbn-xsrf
< access-control-max-age: 86400
< access-control-expose-headers: WWW-Authenticate,Server-Authorization
< kbn-name: BLACK-BOX.local
< kbn-license-sig: 1cccf55bcaa750c426f236ee91ff4acb72269ee63fe20643609db612ae086723
< cache-control: private, no-cache, no-store, must-revalidate
< Date: Mon, 08 Mar 2021 22:26:42 GMT
< Connection: keep-alive
< Keep-Alive: timeout=120

Here's an example of a CORS error response from Kibana (when a disallowed request header is used):

% curl -H "Origin: example.com" \
 -H "Access-Control-Request-Method: GET" \
 -H "Access-Control-Request-Headers: Foo" \
 -X OPTIONS --verbose https://black-box.local:5601/

...

< HTTP/1.1 200 OK
< kbn-name: BLACK-BOX.local
< kbn-license-sig: 1cccf55bcaa750c426f236ee91ff4acb72269ee63fe20643609db612ae086723
< content-type: application/json; charset=utf-8
< cache-control: private, no-cache, no-store, must-revalidate
< content-length: 54
< Date: Mon, 08 Mar 2021 22:30:49 GMT
< Connection: keep-alive
< Keep-Alive: timeout=120

< {"message":"CORS error: Some headers are not allowed"}

So in the "Origin: null" case, we could return an HTTP 200 with a message "CORS error: Origin 'null' is not allowed".

CC @legrego

pgayvallet commented 3 years ago

@jportner Do you know if your suggested changes can be performed on top of HAPI, or would they requires upstream modifications

jportner commented 3 years ago

@jportner Do you know if your suggested changes can be performed on top of HAPI, or would they requires upstream modifications

I'm not sure, I'm honestly not super familiar with the inner workings of Hapi, we might be able to do this all on top of Hapi but I think it needs some investigation.

pgayvallet commented 2 months ago

@legrego What's the status on that one? Is it worth keeping it open or can we close it?

legrego commented 2 months ago

@pgayvallet this isn't currently scheduled, but I believe it's still worth tracking