Issues with CORS


I have been trying to configure my CORS headers properly and while the dev server works fine with this labels:

      - traefik.http.middlewares.corsHeader.headers.accesscontrolalloworiginlist=*
      - traefik.http.middlewares.corsHeader.headers.accesscontrolallowcredentials=true
      - traefik.http.routers.web.middlewares=corsHeader@docker,secureHeaders@file

I just can't make production work with a real list of origins. The page comes with no CORS headers:

HTTP/2 200 OK
content-language: en
content-security-policy: ...
date: Wed, 08 Jul 2020 13:25:47 GMT
referrer-policy: strict-origin
strict-transport-security: max-age=63072000; includeSubDomains; preload
vary: Accept-Language, Cookie,Origin
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 1; mode=block
content-length: 18308
X-Firefox-Spdy: h2

My prod labels look like this:

      - traefik.http.middlewares.corsHeader.headers.accesscontrolallowmethods=GET,POST,OPTIONS,DELETE,PUT
      - traefik.http.middlewares.corsHeader.headers.accesscontrolallowcredentials=false
      - traefik.http.middlewares.corsHeader.headers.accesscontrolmaxage=100
      - traefik.http.middlewares.corsHeader.headers.addvaryheader=true
      - traefik.http.routers.web.middlewares=corsHeader@docker,secureHeaders@file

I tried urls with https and without https in the list and nothing. I also tried adding the configuration using a file provider but same results, no headers in the response.

I'm running 2.2.1 and the secureHeaders middleware is defined as follows:

    frameDeny = true
    sslRedirect = true
    stsSeconds = 63072000
    stsIncludeSubdomains = true
    stsPreload = true
    contentTypeNosniff = true
    browserXssFilter = true
    contentSecurityPolicy = "..."
        Server = ""

I have google around but found no example of a CORS configuration and I have run out of ideas. Hope some one can give me hand. Thank you.

Its been a while since I set this up. Those CORS headers may not be sent unless triggered by a request that requires them. In most cases an origin header.

How are you currently testing?

I'm checking In the browser with the developer tools, if I configure first set of labels above with originlist=* all responses have the header:

HTTP/2 200 OK
access-control-allow-credentials: true
access-control-allow-origin: *
content-language: en
content-security-policy: ...
content-type: text/html; charset=utf-8
date: Thu, 09 Jul 2020 13:36:36 GMT
referrer-policy: strict-origin
strict-transport-security: max-age=63072000; includeSubDomains; preload
vary: Accept-Language, Cookie
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 1; mode=block
content-length: 18467
X-Firefox-Spdy: h2

But if configure a domain list no header is set.

CORS is very request dependent. I found it a little complex. And is why I specifically asked how you are testing. If you are using chrome you may not actually be seeing the preflight requests, I use firefox.

Yes you should be using the full scheme://host.domain format in the accesscontrolalloworiginlist.

To get the requests I needed for testing I ran without cors headers and found a pre-flight request (OPTIONS request). I copied as cURL and used that for my testing.

I would observe the access-control-allow-origin header. I would then change the origin header in the request to a domain not in the CORS list and observe the access-control-allow-origin was not present.

The anatomy of the pre-flight request will have components that look like:

curl '' -X OPTIONS -H 'Access-Control-Request-Method: POST'  -H 'Origin:' -i

HTTP/2 200 
access-control-allow-credentials: true
access-control-allow-headers: Authorization,Origin,Content-Type,Accept
access-control-allow-methods: GET,POST,HEAD,PUT,DELETE,PATCH,OPTIONS
access-control-max-age: 0
content-length: 0
date: Fri, 10 Jul 2020 12:58:05 GMT

You were right. I was thinking this wrong and testing it was more complicated than I thought.

So things I was doing wrong in case someone else finds this post later on.

  • I was trying to reuse middleware configurations, so I had multiple headers middlewares with different configurations that should compliment each other (I was trying to reuse the parts that were identical in different services and only add differences to a different middleware). That was totally breaking and configuration got lost.
  • I was understanding CORS wrong. We're using a CDN that will get CORS config from the source server and then apply it when serving files and I added the CDN to my CORS allow list, but when I tried loading the page from the site it failed since the origin (my own domain) was not on the list.
  • I was testing it wrong I thought that the full list of values should appear as header of my response.

Thank you for your help.

1 Like