Firebase Callable Function: How to restrict CORS origin

Viewed 258

Firebase Callable Functions supports CORS by default. This is good, but it seems to allow requests from any origin by default. How how do I restrict CORS requests to specific origins?

For example, here is a preflight request example (simplified for demonstration purposes):

OPTIONS /callFunctionName HTTP/1.1
authority: us-central1-project-id.cloudfunctions.net
access-control-request-method: POST
access-control-request-headers: authorization,content-type
origin: https://foo.example.com
sec-fetch-mode: cors
sec-fetch-site: cross-site
sec-fetch-dest: empty

Response (simplified):

HTTP/1.1 204 No Content
Access-Control-Allow-Headers: authorization,content-type
Access-Control-Allow-Methods: POST
Access-Control-Allow-Origin: https://foo.example.com
Content-Length: 0

As the Access-Control-Allow-Origin responds with the request origin, the CORS request will always be allowed by the browser. How can I restrict this?

2 Answers

Unfortunately, what you want is not possible. Response headers for callable functions only allow Content-Type and an optional charset. If you need control and restrict CORS or any part of the protocol that deviates from what's implemented by Firebase Callable Functions, you should instead use a normal HTTP function and implement those details as mentioned in this answer.

To handle a preflight request using HTTP function, you must set the appropriate Access-Control-Allow-* response headers.

Here's a sample nodejs code that handles preflight request:

/**
 * HTTP function that supports CORS requests.
 *
 * @param {Object} req Cloud Function request context.
 * @param {Object} res Cloud Function response context.
 */
exports.corsEnabledFunction = (req, res) => {
  // Set CORS headers for preflight requests
  // and caches preflight response for 3600s

  res.set('Access-Control-Allow-Origin', 'your-allowed-origin');
  // Allows GETs from your specified origin with the Content-Type header

  if (req.method === 'OPTIONS') {
    // Send response to OPTIONS requests
    res.set('Access-Control-Allow-Methods', 'GET');
    res.set('Access-Control-Allow-Headers', 'Content-Type');
    res.set('Access-Control-Max-Age', '3600');
    res.status(204).send('');
  } else {
    res.send('Hello World!');
  }
};

Alternatively, you can use a third-party library to handle CORS for you.

You may also refer to this documentation for more information.

It looks like a Pull Request was submitted that allows us to white-list cors origins for callable functions: https://github.com/firebase/firebase-functions/pull/986

The PR was closed due to changes in upcoming API design, but it sounds like the Firebase team is working on adding this option.

Related