From 54a4c0b4121e3df13913fbdb7045727b282e5a76 Mon Sep 17 00:00:00 2001 From: patrick brisbin Date: Fri, 10 May 2024 10:04:06 -0400 Subject: [PATCH] Add Vary: Origin to CORS response headers Because the middleware is designed to allow multiple possible origins, by sending back the origin given as `Access-Control-Allowed-Origin` (if it's valid), we need to ensure those responses aren't cached and served to other origins, otherwise they will get CORS errors. Practically speaking, the request `Origin` should factor into any cache-key. According to the HTTP spec, you do this by including that header in `Vary`, so that's what this change does. Unfortunately, this may not always work. Fastly is known to work correctly[^1] but CloudFront does not[^2]. For CloudFront, you also have to configure your distribution itself to include `Origin` in the cache key via your `CachePolicy`, and this `Vary` header is ignored. [^1]: https://www.fastly.com/blog/getting-most-out-vary-fastly [^2]: https://stackoverflow.com/a/16546364 --- library/Network/Wai/Middleware/Cors.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/Network/Wai/Middleware/Cors.hs b/library/Network/Wai/Middleware/Cors.hs index c7a980fb..2ca07cb8 100644 --- a/library/Network/Wai/Middleware/Cors.hs +++ b/library/Network/Wai/Middleware/Cors.hs @@ -60,6 +60,7 @@ corsResponseHeaders validateOrigin extraExposedHeaders origin = , ("Access-Control-Allow-Credentials", "true") , ("Access-Control-Allow-Headers", "Content-Type, *") , ("Access-Control-Expose-Headers", BS.intercalate ", " exposedHeaders) + , ("Vary", "Origin") ] where validatedOrigin = if validateOrigin origin then origin else "BADORIGIN"