CORS middleware behaviour change - dropping Access-Control-Allow-Headers header
See original GitHub issueIn the pre CORSPolicy
implementation, if a preflight request included a header in Access-Control-Request-Headers
that was not permitted by the CORS configuration, the CORS middleware would return a Access-Control-Allow-Headers
header with the list of allowed headers. In the current implementation (so 0.23.3+, and not sure the equivalent for 1.0.0-x and 0.22.x) if the request header has more fields than are allowed, the response header gets dropped.
Example in 0.23.4
import cats.effect.IO
import cats.effect.unsafe.implicits._
import org.http4s.server.middleware.CORS
import org.http4s._
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import org.typelevel.ci.CIStringSyntax
class CORSTest extends AnyFlatSpec with Matchers {
val cors = CORS.policy.withAllowHeadersIn(Set(ci"Foo", ci"Bar")).withAllowMethodsAll
val routes = cors(HttpRoutes.pure[IO](Response[IO]())).orNotFound
val request =
Request[IO](
method = Method.OPTIONS,
headers = Headers(
Header.Raw(ci"Origin", "http://example.com"),
Header.Raw(ci"Access-Control-Request-Headers", "foo, faz"), //faz not allowed, foo is
Header.Raw(ci"Access-Control-Request-Method", "POST")
)
)
//FAILS
it should "have an Access-Control-Allow-Headers header" in {
//this header should be present and have value "Foo,Bar", but is missing
routes(request).unsafeRunSync().headers.get(ci"Access-Control-Allow-Headers").isDefined shouldBe true
}
}
and here is a worksheet using the old CORSConfig implementation where we see that the header is still returned under these circumstances https://scastie.scala-lang.org/6WjBVGOVRRy3vYGv4YZ6Qg
Issue Analytics
- State:
- Created 2 years ago
- Comments:7 (7 by maintainers)
Top Results From Across the Web
No 'Access-Control-Allow-Origin' header is present on the ...
This answer covers a lot of ground, so it's divided into three parts: How to use a CORS proxy to avoid “No Access-Control-Allow-Origin ......
Read more >Enable Cross-Origin Requests (CORS) in ASP.NET Core
There are three ways to enable CORS: In middleware using a named policy or default policy. Using endpoint routing. With the [EnableCors] ...
Read more >koajs/cors: Cross-Origin Resource Sharing(CORS) for koa
Quick start. Enable cors with default options: origin: request Origin header; allowMethods: GET,HEAD,PUT,POST,DELETE,PATCH.
Read more >3 Ways to Fix the CORS Error — and How the Access-Control ...
The proxy uses express middleware to apply a Access-Control-Allow-Origin: * header to every response from the server. At its own jokes/random ...
Read more >Your Complete API Gateway and CORS Guide
I won't provide any information on CORS headers for WebSocket API as it isn't ... Access-Control-Allow-Headers: true method.response.header.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
The CORS spec is very frustrating. The old one covered the server side in detail, but the replacement says next to nothing.
In the old spec, in Step 6, it says:
where “header field-names” is from
Access-Control-Request-Headers
and “list of headers” are the supported headers we would return inAccess-Control-Allow-Headers
. So per the old spec, I think the current behavior is correct. I also referenced popular implementations from other languages while working on the CVE, and I don’t think we’re on an island here.That said, I’m struggling with why it should be a guessing game. Because the allowed headers can be unbounded but wildcards are incompatible with other settings, some CORS implementations exploit the matching rule to return a finite set of headers based on reflecting the request. Aside from that, I don’t know why it shouldn’t just return the full set of headers. But the spec authors have usually thought deeper than me. I’d be interested to dig up their reasons.
From the linked ticket, it looks like the relaxation is intentional in the new spec. I think that puts Option A back on the table. The question is if anybody prefers the Old Spec behavior vs. the Old Http4s behavior.