CORS Middleware not working

Hello,

I have created following middleware for API endpoint

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: cors-api
  namespace: api-staging
spec:
  headers:
    accessControlAllowMethods:
      - "GET"
      - "OPTIONS"
      - "PUT"
      - "POST"
      - "DELETE"
    accessControlAllowHeaders:
      - "*"
    accessControlAllowOriginList:
      - "https://*.example.com"
    accessControlMaxAge: 100
    addVaryHeader: true

& attached it to IngressRoute

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: api-external-0
  namespace: api-staging
spec:
  entryPoints:
    - web
    - websecure
  routes:
    - kind: Rule
      match: Host(`api.staging.example.com`)
      services:
        - name: nginx
          port: 80
          strategy: RoundRobin
          sticky:
            cookie:
              httpOnly: true
      middlewares:
        - name: cors-api
          namespace: api-staging
        - name: https-redirect
          namespace: api-staging
  tls:
    secretName: staging-cert

But following request is going through

% curl -v --request OPTIONS 'https://api.staging.example.com' -H 'Origin: http://fake.origin.com' -H 'Access-Control-Request-Method: GET'
*   Trying x.x.x.x:443...
* Connected to api.staging.example.com (x.x.x.x) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-AES128-GCM-SHA256
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=*.staging.example.com
*  start date: Jan 11 02:15:45 2024 GMT
*  expire date: Apr 10 02:15:44 2024 GMT
*  subjectAltName: host "api.staging.example.com" matched cert's "*.staging.example.com"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://api.staging.example.com/
* [HTTP/2] [1] [:method: OPTIONS]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: api.staging.example.com]
* [HTTP/2] [1] [:path: /]
* [HTTP/2] [1] [user-agent: curl/8.4.0]
* [HTTP/2] [1] [accept: */*]
* [HTTP/2] [1] [origin: http://fake.origin.com]
* [HTTP/2] [1] [access-control-request-method: GET]
> OPTIONS / HTTP/2
> Host: api.staging.example.com
> User-Agent: curl/8.4.0
> Accept: */*
> Origin: http://fake.origin.com
> Access-Control-Request-Method: GET
>
< HTTP/2 200
< access-control-allow-headers: *
< access-control-allow-methods: GET,OPTIONS,PUT,POST,DELETE
< access-control-max-age: 100
< content-length: 0
< date: Mon, 19 Feb 2024 17:54:27 GMT
<
* Connection #0 to host api.staging.example.com left intact

Any thoughts on what is happening here ?

Hmm, you are setting a header, so that sends info for the client to not load scrips from other sites. But I don’t think it will have an effect on curl requests.

Do I need to fix anything in CROS Middleware

I tried following option as well but no luck

accessControlAllowOriginListRegex:
  - "(.*?)\\.example\\.com"

Can you explain again what you are trying to achieve and what you expect to see when using curl?

I want to use CORS to block curl request if its not using approved Origin in a request. Only requests with predefined Origin should pass through or conects.

CORS is not used on server to actively block requests. The server sends CORS headers, but the client browser needs to enforce it.

From ChatGPT:

CORS (Cross-Origin Resource Sharing) is a security feature implemented on web servers to specify who can access the resources on the server. It works by adding specific headers to HTTP responses. Although the rules are set on the server, the enforcement of these rules occurs on the client side. Browsers read the CORS headers in responses from the server and decide whether to allow or block the resource from being accessed by the web page, based on the origin of the page making the request.

So with a single request tool like curl you won’t see any effect. You could try lynx on the command line, which is a full terminal browser.