web-dev-qa-db-fra.com

Sécuriser le déclencheur http de Google Cloud Functions avec authentification

J'essaie aujourd'hui Google Cloud Functions en suivant ce guide: https://cloud.google.com/functions/docs/quickstart

J'ai créé une fonction avec un déclencheur HTTP et j'ai pu exécuter une demande POST pour déclencher une fonction à écrire dans le magasin de données.

Je me demandais s'il y avait un moyen de sécuriser ce point de terminaison HTTP? Actuellement, il semble qu'il acceptera une demande de n'importe où/de n'importe qui.

En parcourant Google, je vois que la plupart des résultats parlent de sécuriser les choses avec Firebase. Cependant, je n'utilise pas le service Firebase ici.

Mes options seraient-elles soit laissées ouvertes, et j'espère que personne ne connaît le point de terminaison URL (sécurité par obscurité), soit implémenter ma propre vérification d'authentification dans la fonction elle-même?

33
Tri Nguyen

Après avoir approfondi cela et pris un indice de la réponse de @ ricka, j'ai décidé d'implémenter une vérification d'authentification pour mes fonctions cloud avec un jeton JWT transmis sous la forme d'un jeton d'accès d'en-tête d'autorisation.

Voici l'implémentation dans Node:

const client = jwksClient({
  cache: true,
  rateLimit: true,
  jwksRequestsPerMinute: 5,
  jwksUri: "https://<auth0-account>.auth0.com/.well-known/jwks.json"
});

function verifyToken(token, cb) {
  let decodedToken;
  try {
    decodedToken = jwt.decode(token, {complete: true});
  } catch (e) {
    console.error(e);
    cb(e);
    return;
  }
  client.getSigningKey(decodedToken.header.kid, function (err, key) {
    if (err) {
      console.error(err);
      cb(err);
      return;
    }
    const signingKey = key.publicKey || key.rsaPublicKey;
    jwt.verify(token, signingKey, function (err, decoded) {
      if (err) {
        console.error(err);
        cb(err);
        return
      }
      console.log(decoded);
      cb(null, decoded);
    });
  });
}

function checkAuth (fn) {
  return function (req, res) {
    if (!req.headers || !req.headers.authorization) {
      res.status(401).send('No authorization token found.');
      return;
    }
    const parts = req.headers.authorization.split(' ');
    if (parts.length != 2) {
      res.status(401).send('Bad credential format.');
      return;
    }
    const scheme = parts[0];
    const credentials = parts[1];

    if (!/^Bearer$/i.test(scheme)) {
      res.status(401).send('Bad credential format.');
      return;
    }
    verifyToken(credentials, function (err) {
      if (err) {
        res.status(401).send('Invalid token');
        return;
      }
      fn(req, res);
    });
  };
}

J'utilise jsonwebtoken pour vérifier le jeton JWT et jwks-rsa pour récupérer la clé publique. J'utilise Auth0, donc jwks-rsa atteint la liste des clés publiques pour les récupérer.

La fonction checkAuth peut alors être utilisée pour sauvegarder la fonction cloud comme:

exports.get = checkAuth(function (req, res) {
    // do things safely here
});

Vous pouvez voir ce changement sur mon dépôt github à https://github.com/tnguyen14/functions-datastore/commit/a6b32704f0b0a50cd719df8c1239f993ef74dab6

Le jeton JWT/access peut être récupéré de différentes manières. Pour Auth0, le document API peut être trouvé à https://auth0.com/docs/api/authentication#authorize-client

Une fois que cela est en place, vous pouvez déclencher la fonction cloud (si la vôtre est activée avec le déclencheur http) avec quelque chose comme

curl -X POST -H "Content-Type: application/json" \
-H "Authorization: Bearer access-token" \
-d '{"foo": "bar"}' \
"https://<cloud-function-endpoint>.cloudfunctions.net/get"
12
Tri Nguyen

Il semble qu'il existe actuellement 2 façons de sécuriser un point de terminaison HTTP Google Cloud Function.

1) Utilisez un nom de fonction difficile à deviner (ex: my-function-vrf55m6f5Dvkrerytf35)

2) Vérifiez le mot de passe/les informations d'identification/la demande signée dans la fonction elle-même (en utilisant un en-tête ou un paramètre)

Il vaut probablement mieux faire les deux.

1
ricka

Vous pouvez créer un algorithme d'authentification personnalisé pour vérifier le client.

Découvrez l'algorithme de; https://security.stackexchange.com/q/210085/22239

0
Berkay Turancı

Vous ne devez pas "le laisser ouvert et espérer que personne ne le sait". Vous pouvez implémenter votre propre contrôle de sécurité ou vous pouvez essayer le module Google Function Authorizer ( https://www.npmjs.com/package/google-function-authorizer ).

0
Darren