0

My API cluster is under kubernetes.

    if (!configService.isProduction()) {
        app.enableCors();
    } else {
        const whitelist = ['https://sub. domain .com', 'https:// www.domain .com', 'undefined'];
        app.enableCors({
            origin: function (origin, callback) {
                if (whitelist.indexOf(origin) !== -1) {
                    console.log("allowed cors for:", origin)
                    callback(null, true)
                } else {
                    console.log("blocked cors for:", origin)
                    callback(new Error('Not allowed by CORS'))
                }
            },
            allowedHeaders: 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept, Observe',
            methods: "GET,PUT,POST,DELETE,UPDATE,OPTIONS",
            credentials: true,
        });
    }

The problem here is when the deployment up Kubernetes try to run a health check and fails at origin, origin return as undefined. Added to my whitelist undefined value, it didn't work.

What is the best way to limit access to my API?

AndreyKh.
  • 1
  • 1

1 Answers1

0

Origin headers can be faked in non-browser environments, so using CORS to try to prevent unauthorized access to your API is not a secure solution.

CORS is specifically meant to prevent browsers from making requests cross-domain to servers that do not have the appropriate CORS headers. It's not designed to protect the server; it's designed to protect the browser and the user.

Assuming you're actually wanting to secure and authenticate your api, you have a couple easy options here:

  1. Remove authentication for your health check endpoint (not recommended)
  2. Use HTTP headers in your livenessProbe to authenticate Kubernetes:

Something like this should work. Note that you could use any kind of authentication headers you want here.

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/liveness
    args:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        # Add basic auth, or any other auth mechanism you want here:
        # Make sure to use your own user:password in Base64 if you copy/paste
        httpHeaders:
        - name: Authorization
          value: Basic dXNlcjpwYXNzd29yZA==
      initialDelaySeconds: 3
      periodSeconds: 3

There's other ways that you could achieve this, but without more information on the rest of your cluster it's hard to provide you with a better answer.

I would also highly recommend that you don't deny requests with the origin function. Generally speaking, that's used to dynamically configure the CORS whitelist, and the error is used to signal that something went wrong while configuring it. It gives a false sense of security, since the origin header can be spoofed by any non-browser request library.

Here is a great answer on CORS and what it's used for.

HMilbradt
  • 3,980
  • 16
  • 31
  • Thanks! why not to remove authentication for health check? why do I care if one tries to reach it ? – Dejell Apr 18 '22 at 13:21