From 94261d2f60507a25d6a20773dd1bf763b6fbe6c8 Mon Sep 17 00:00:00 2001 From: Damian Sawicki Date: Wed, 26 Nov 2025 16:09:21 +0000 Subject: [PATCH] Rectify credentialed requests vs allowCredentials This is a fix to GEP-1767. It specifies that wildcards are not allowed in CORS response headers when the request is credentialed (rather than when the allowCredentials config field is true). The corresponding GitHub Issue is https://github.com/kubernetes-sigs/gateway-api/issues/3861. Signed-off-by: Damian Sawicki --- geps/gep-1767/index.md | 69 ++++++++++++++++++++++++++++--------- geps/gep-1767/metadata.yaml | 2 ++ 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/geps/gep-1767/index.md b/geps/gep-1767/index.md index 14315e190c..71ba55da53 100644 --- a/geps/gep-1767/index.md +++ b/geps/gep-1767/index.md @@ -51,6 +51,7 @@ The optional response header `Access-Control-Expose-Headers` controls which HTTP If the server specifies the response header `Access-Control-Allow-Credentials: true`, the actual cross-origin request will be able to use credentials for getting sensitive resources. Credentials are cookies, TLS client certificates, or authentication headers containing a username and password. +A "credentialed request" is a request containing some credentials. After the server has permitted the CORS "preflight" request, the client will be able to send actual cross-origin request. If the server doesn't want to allow cross-origin access, it will omit the CORS headers to the client. @@ -211,8 +212,24 @@ type HTTPCORSFilter struct { // // Output: // - // The `Access-Control-Allow-Origin` response header can only use `*` - // wildcard as value when the `AllowCredentials` field is false. + // Conversely, if the request `Origin` matches one of the configured + // allowed origins, the gateway sets the response header + // `Access-Control-Allow-Origin` to the same value as the `Origin` + // header provided by the client. + // + // Input: + // Origin: https://foo.example + // + // Config: + // allowOrigins: ["https://foo.example", "http://test.example"] + // + // Output: + // Access-Control-Allow-Origin: https://foo.example + // + // When config has the wildcard ("*") in allowOrigins, and the request + // is not credentialed (e.g., it is a preflight request), the + // `Access-Control-Allow-Origin` response header contains the + // wildcard as well. // // Input: // Origin: https://foo.example @@ -223,8 +240,8 @@ type HTTPCORSFilter struct { // Output: // Access-Control-Allow-Origin: * // - // When the `AllowCredentials` field is true and `AllowOrigins` - // field specified with the `*` wildcard, the gateway must return a + // When the `allowOrigins` config field contains the "*" wildcard and the + // request is credentialed, the gateway must return a // single origin in the value of the `Access-Control-Allow-Origin` // response header, instead of specifying the `*` wildcard. The value // of the header `Access-Control-Allow-Origin` is same as the `Origin` @@ -232,6 +249,7 @@ type HTTPCORSFilter struct { // // Input: // Origin: https://foo.example + // Cookie: pageAccess=2 // // Config: // allowOrigins: ["*"] @@ -304,8 +322,9 @@ type HTTPCORSFilter struct { // Output: // Access-Control-Allow-Methods: GET, POST, DELETE, PATCH, OPTIONS // - // The `Access-Control-Allow-Methods` response header can only use `*` - // wildcard as value when the `AllowCredentials` field is false. + // The `Access-Control-Allow-Methods` response header should use `*` + // wildcard as value if config contains the wildcard "*" in allowMethods + // unless the request is credentialed. // // Input: // Access-Control-Request-Method: PUT @@ -316,8 +335,8 @@ type HTTPCORSFilter struct { // Output: // Access-Control-Allow-Methods: * // - // When the `AllowCredentials` field is true and the `AllowMethods` - // field specified with the `*` wildcard, the gateway must specify one + // When the `allowCredentials` config field is true and the request is + // credentialed, the gateway must specify one // HTTP method in the value of the Access-Control-Allow-Methods response // header. The value of the header `Access-Control-Allow-Methods` is same // as the `Access-Control-Request-Method` header provided by the client. @@ -329,6 +348,7 @@ type HTTPCORSFilter struct { // // Input: // Access-Control-Request-Method: PUT + // Cookie: pageAccess=2 // // Config: // allowMethods: ["*"] @@ -363,6 +383,9 @@ type HTTPCORSFilter struct { // If any header name in the `Access-Control-Allow-Headers` response header does // not recognize by the client, it will also occur an error on the client side. // + // A Gateway implementation may choose to add implementation-specific + // default headers. + // // Input: // Access-Control-Request-Headers: Cache-Control, Content-Type // @@ -373,8 +396,9 @@ type HTTPCORSFilter struct { // Access-Control-Allow-Headers: DNT, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Range, Authorization // // A wildcard indicates that the requests with all HTTP headers are allowed. - // The `Access-Control-Allow-Headers` response header can only use `*` wildcard - // as value when the `AllowCredentials` field is false. + // The `Access-Control-Allow-Headers` response header should use the `*` + // wildcard as value if the `allowHeaders` config field contains the "*" + // wildcard unless the request is credentialed. // // Input: // Access-Control-Request-Headers: Content-Type, Cache-Control @@ -385,18 +409,18 @@ type HTTPCORSFilter struct { // Output: // Access-Control-Allow-Headers: * // - // When the `AllowCredentials` field is true and the `AllowHeaders` field - // is specified with the `*` wildcard, the gateway must specify one or more + // When the `allowHeaders` config field contains the "*" wildcard and the request + // is credentialed, the gateway must specify one or more // HTTP headers in the value of the `Access-Control-Allow-Headers` response // header. The value of the header `Access-Control-Allow-Headers` is same as // the `Access-Control-Request-Headers` header provided by the client. If // the header `Access-Control-Request-Headers` is not included in the request, // the gateway will omit the `Access-Control-Allow-Headers` response header, - // instead of specifying the `*` wildcard. A Gateway implementation may choose - // to add implementation-specific default headers. + // instead of specifying the `*` wildcard. // // Input: // Access-Control-Request-Headers: Content-Type, Cache-Control + // Cookie: pageAccess=2 // // Config: // allowHeaders: ["*"] @@ -443,8 +467,8 @@ type HTTPCORSFilter struct { // Access-Control-Expose-Headers: Content-Security-Policy, Content-Encoding // // A wildcard indicates that the responses with all HTTP headers are exposed - // to clients. The `Access-Control-Expose-Headers` response header can only use - // `*` wildcard as value when the `AllowCredentials` field is false. + // to clients. The `Access-Control-Expose-Headers` response header should use + // the `*` wildcard as value unless the request is credentialed. // // Config: // exposeHeaders: ["*"] @@ -452,6 +476,19 @@ type HTTPCORSFilter struct { // Output: // Access-Control-Expose-Headers: * // + // When the `exposeHeaders` config field contains the "*" wildcard and + // the request is credentialed, the gateway cannot use the `*` wildcard in + // the `Access-Control-Expose-Headers` response header. + // + // Input: + // Cookie: pageAccess=2 + // + // Config: + // exposeHeaders: ["*"] + // + // Output: + // Access-Control-Expose-Headers: Content-Encoding, Kuma-Revision + // // Support: Extended // // +optional diff --git a/geps/gep-1767/metadata.yaml b/geps/gep-1767/metadata.yaml index e319aacd1c..8594a4074e 100644 --- a/geps/gep-1767/metadata.yaml +++ b/geps/gep-1767/metadata.yaml @@ -8,9 +8,11 @@ authors: - robscott - EyalPazz - shaneutt + - DamianSawicki references: - https://github.com/kubernetes-sigs/gateway-api/pull/3435 - https://github.com/kubernetes-sigs/gateway-api/pull/3637 - https://github.com/kubernetes-sigs/gateway-api/pull/3656 - https://github.com/kubernetes-sigs/gateway-api/pull/3668 + - https://github.com/kubernetes-sigs/gateway-api/pull/4281