Passer au contenu principal
Publié : 10 janvier 2019

Vue d’ensemble

Ce bulletin de sécurité présente plusieurs scénarios que les clients devraient éviter dans le code de Rule personnalisé, car ils peuvent créer des vulnérabilités dans le flux d’authentification. Une description de chaque problème et, lorsque possible, une autre façon d’écrire la même Rule sont fournies ci-dessous.
  • Le code de Rule personnalisé contenant une logique conditionnelle pour appliquer (MFA) peut permettre de contourner complètement la MFA, surtout lors de l’utilisation de l’authentification silencieuse.
  • Le code de Rule personnalisé qui met en œuvre des contrôles d’autorisation fondés sur une sous-chaîne précise sans logique appropriée peut entraîner une élévation de privilèges.
  • Le code de Rule personnalisé qui envoie des renseignements de diagnostic à des services tiers, plutôt que d’utiliser les fonctionnalités de débogage intégrées d’Auth0, peut entraîner la divulgation de renseignements sensibles.
  • Le code de Rule personnalisé qui déclenche des services payants peut permettre à un adversaire d’engendrer des frais de facturation indésirables.
  • Le code de Rule personnalisé qui accorde des autorisations en fonction d’adresses de courriel non vérifiées peut permettre à des adversaires d’obtenir ces privilèges au moyen d’un type de connexion secondaire.
  • Le code de Rule personnalisé contenant des secrets codés en dur, comme des clés API, au lieu d’utiliser l’objet de configuration global, augmente le risque d’exposer ces secrets.

Rules MFA incorrectes

Authentification silencieuse

Dans une application monopage (SPA), l’authentification silencieuse permet d’émettre de nouveaux sans interaction de l’utilisateur, tant que la session en cours demeure valide auprès du . Auth0 offre l’authentification silencieuse au moyen d’un paramètre spécial ajouté au point de terminaison d’autorisation, comme suit : /authorize?prompt=none Toutefois, si la MFA est ajoutée au processus d’authentification silencieuse, une interaction de l’utilisateur devient nécessaire. Il ne faut pas utiliser une logique conditionnelle fondée sur l’authentification silencieuse comme solution de contournement de la MFA. De telles Rules permettent un contournement complet de la MFA et ne doivent pas être utilisées :
function (user, context, callback) {
  if (context.request.query && context.request.query.prompt === 'none') {
  // ignorer la MFA pour les demandes de jetons silencieux
  return callback(null, user, context);
  }
...
}

Authentification silencieuse avec redirection vers un fournisseur de MFA personnalisé

Les Rules qui déterminent, en fonction de l’authentification silencieuse, s’il faut rediriger vers un fournisseur d’authentification multifacteur personnalisé peuvent, dans certaines circonstances inhabituelles, permettre un contournement de la MFA. Par exemple, évitez ce qui suit :
function (user, context, callback) {
  if (context.request.query && context.request.query.prompt === 'none') {
  //rediriger vers le MFA personnalisé
  context.redirect = {
    url: "https://example.com/"
  };
...
}

Vérification inadéquate

L’utilisation de Rules pour contourner l’authentification multifacteur dans certaines conditions peut permettre de contourner la MFA lorsque les vérifications en place ne permettent pas d’établir adéquatement la validité de l’état attendu. Dans ces cas, le problème fondamental est que les Rules ne peuvent jamais déterminer si la MFA a bien été exécutée, puisque la MFA survient après leur exécution. Les Rules configurées de cette façon (voir les exemples ci-dessous) mettent à jour prématurément le profil de l’utilisateur en supposant à tort que la MFA sera exécutée avec succès, tout en s’appuyant sur ce même profil utilisateur pour ignorer la MFA dans certaines conditions. Les exemples ci-dessous illustrent des vérifications inadéquates pouvant entraîner un contournement complet de l’authentification multifacteur.

Empreinte de l’appareil

function (user, context, callback) {

  var crypto = require('crypto');

  var deviceFingerPrint = getDeviceFingerPrint();
  user.app_metadata = user.app_metadata || {};

  // Vérification inadéquate
  if (user.app_metadata.lastLoginDeviceFingerPrint !== deviceFingerPrint) {
    user.app_metadata.lastLoginDeviceFingerPrint = deviceFingerPrint;
    context.multi-factor = {
      ...
    };
    ...
  }
  function getDeviceFingerPrint() {
    var shasum = crypto.createHash('sha1');
    shasum.update(context.request.userAgent);
    shasum.update(context.request.ip);
    return shasum.digest('hex');
  }
}

Code de pays

function (user, context, callback) {
  user.app_metadata = user.app_metadata || {};

  // Vérification insuffisante
  if (user.app_metadata.last_location !== context.request.geoip.country_code) {
    user.app_metadata.last_location = context.request.geoip.country_code;
    context.multi-factor = {
    ...
    };
  }

Suis-je concerné ?

Si vous utilisez l’une des logiques de Rule illustrées précédemment, un adversaire qui s’est authentifié avec succès à l’aide du premier facteur pourrait être en mesure de contourner la MFA dans votre application.

Étapes d’atténuation

Si le scénario d’authentification silencieuse vous concerne, supprimez la logique conditionnelle fondée sur prompt === 'none'. Cela déclenchera l’authentification multifacteur à chaque appel d’authentification silencieuse pour vérifier l’état de la session. Si le scénario d’authentification silencieuse avec redirection vous concerne, supprimez la logique conditionnelle fondée sur prompt === 'none' et passez à un fournisseur d’authentification multifacteur pris en charge par Auth0. Pour éviter de demander trop souvent la MFA à l’utilisateur, vous pouvez définir le paramètre allowRememberBrowser sur true, ce qui permettra aux utilisateurs finaux de cocher une case afin qu’ils n’aient à effectuer l’authentification multifacteur que tous les 30 jours. Par exemple :
context.multi-factor = {
    provider: 'guardian',
    allowRememberBrowser: true
  };
Vous pourriez envisager d’informer vos utilisateurs finaux qu’ils doivent cocher la case pour éviter qu’on leur demande trop souvent de le faire. Si vous êtes concerné par des Rules qui utilisent une vérification inadéquate pour contourner la MFA, assurez-vous d’utiliser des mécanismes de vérification fiables, d’éliminer complètement les exceptions à la MFA ou d’utiliser l’option de configuration allowRememberBrowser décrite ci-dessus.

Cette mise à jour aura-t-elle une incidence sur mes utilisateurs?

Selon la façon dont vous ajustez vos Rules ou votre configuration, cette mise à jour peut avoir une incidence sur vos utilisateurs en leur demandant de recourir à la MFA plus souvent qu’à l’habitude.

Vérification inadéquate des sous-chaînes

Si la logique de votre Rule exige un contrôle d’accès fondé sur une correspondance exacte pour une chaîne donnée, comme un domaine de courriel, mais que vous vérifiez seulement la présence d’une sous-chaîne au lieu d’une correspondance exacte, il se peut que votre logique ne fonctionne pas comme prévu. Par exemple : if( _.findIndex(connection.options.domain_aliases,function(d){ return user.email.indexOf(d) >= 0; La logique ci-dessus renverrait true pour des courriels comme ceux-ci :
  • user.domain.com@not-domain.com
  • "user@domain.com"@not-domain.com (guillemets compris)

Suis-je concerné ?

Seuls les clients qui utilisent une logique conditionnelle dans les Rules, comme décrit ci-dessus, sont concernés.

Étapes d’atténuation

Utilisez une logique comme : const emailSplit = user.email.split('@'); const userEmailDomain = emailSplit[emailSplit.length - 1].toLowerCase(); Pour en savoir plus, consultez le modèle de Rule Check Domains Against Connection Aliases. Sinon, dans la section Rules de l’, consultez le modèle de Rule intitulé Vérifier si le domaine de courriel de l’utilisateur correspond au domaine configuré.

Cette mise à jour aura-t-elle une incidence sur mes utilisateurs ?

Possiblement. La modification recommandée concernant les Rules dont la logique repose sur des vérifications de sous-chaînes peut avoir une incidence sur les utilisateurs finaux. Toutefois, vous êtes le mieux placé pour évaluer l’intention de vos Rules et déterminer si les changements recommandés risquent d’avoir une incidence sur vos utilisateurs finaux.

Débogage à l’aide de services externes

Si vous avez une Rule dont la logique envoie l’objet de contexte Auth0 à un service externe, vous exposez des éléments comme id_token ou access_token associés à la requête. Par exemple :
request.post({
    url: 'http://requestbin.fullcontact.com/YourBinUrl',
    json: {
      user: user,
      context: context,
    },
    timeout: 15000
  }, function(err, response, body){
    if (err) return callback(err);
    return callback(null, user, context);
  });

Suis-je concerné ?

Seuls les clients qui utilisent une logique de Rule, telle que décrite ci-dessus, sont concernés.

Étapes d’atténuation

Vous devriez modifier votre Rule pour qu’elle n’envoie plus l’objet de contexte complet à requestbin, car cela pourrait exposer tout id_token ou access_token associé à chaque requête. Envoyez plutôt un sous-ensemble d’attributs de l’objet de contexte moins sensibles. Consultez le modèle de Rule Requestbin pour en savoir plus. Vous pouvez aussi, dans la section Rules de l’Auth0 Dashboard, consulter le modèle de Rule nommé Dump rule variables to RequestBin. Auth0 offre aussi des méthodes intégrées pour déboguer les Rules sans envoyer d’information à des services externes.

Cette mise à jour aura-t-elle un impact sur mes utilisateurs ?

Non. La Rule concernée était généralement utilisée à des fins de débogage. Cette modification ne devrait pas avoir d’incidence sur les utilisateurs finaux.

Rules qui utilisent un service payant

Si vous avez une logique de Rule qui fait appel à un service payant, comme l’envoi de messages SMS par Twillio, dans le cadre du processus d’authentification, vous pourriez être exposé à une augmentation des coûts. En effet, un adversaire disposant d’un nom d’utilisateur et d’un mot de passe valides pourrait déclencher un appel au service et engendrer des frais sans avoir à mener à terme l’ensemble du processus d’authentification défini par les Rules. Par exemple :
//Envoie un SMS à l'utilisateur via Twilio
  function notifyUser(done) {
    const request = require('request');
    const twilioAccount = '{yourTwilioAccount}';
    const twilioAuthToken = '{yourTwilioAuthToken}';

    request.post({
      url: 'https://api.twilio.com/2010-04-01/Accounts/' + twilioAccount + '/Messages.json',
      auth: {
        'user': twilioAccount,
        'pass': twilioAuthToken,
      },
      form: {
        body: 'You\'ve logged in from a different device or location.',
        to: user.phone,
        from: '+18668888888'
      }
    }, function (error, response, body) {
      if (error) return done(error);
      if (response.statusCode !== 201) return done(new Error(response.statusCode));
      return done(null);
    });
  }

Suis-je concerné ?

Seuls les clients qui utilisent une logique de Rule telle que décrite ci-dessus et dont cette logique peut être déclenchée par tout utilisateur non fiable sont concernés.

Étapes d’atténuation

Pour atténuer ce risque, envisagez l’une ou plusieurs des mesures suivantes :
  • Désactivez les inscriptions publiques, si elles ne sont pas nécessaires, afin de réduire le nombre d’utilisateurs pouvant s’inscrire et déclencher des appels à des services payants.
  • Réduisez le risque de vol d’identifiants afin d’éviter la prise de contrôle de comptes par des pirates qui pourraient utiliser des comptes compromis pour déclencher des appels à des services payants.
  • Assurez-vous que vos utilisateurs ont des mots de passe robustes lorsqu’ils utilisent des connexions de base de données.
  • Assurez-vous que vos utilisateurs utilisent l’authentification multifacteur.
  • Assurez-vous que la Rule n’est déclenchée que pour un sous-ensemble autorisé d’utilisateurs, ou dans d’autres conditions appropriées. Par exemple, vous pouvez ajouter une logique qui vérifie si un utilisateur a un domaine de courriel précis, un rôle/groupe ou un niveau d’abonnement particulier avant de déclencher l’appel au service payant.

Cette mise à jour aura-t-elle une incidence sur mes utilisateurs ?

Les répercussions pour les utilisateurs finaux dépendent de l’option que vous choisissez parmi celles décrites ci-dessus pour atténuer le problème.

Autorisation fondée sur une adresse de courriel non vérifiée

Si la logique de votre Rule exige un contrôle d’accès en fonction d’un courriel précis ou d’un domaine de courriel, mais que vous ne vérifiez pas si l’utilisateur a validé son courriel, un adversaire pourrait obtenir des privilèges supplémentaires en utilisant un deuxième type de connexion. Par exemple :
var userHasAccess = allowList.some(function (email) {
    return email === user.email;
  });
La logique ci-dessus retournerait true si un attaquant pouvait créer un compte à l’aide d’un autre type de connexion (par exemple, une connexion sociale) avec une adresse de courriel figurant dans la liste d’autorisation. Cela se produit parce qu’une même adresse de courriel peut exister dans différents types de connexion.

Suis-je concerné(e) ?

Seuls les clients qui utilisent une logique conditionnelle dans des Rules, comme décrit ci-dessus, et qui autorisent plusieurs types de connexions sont concernés.

Mesures d’atténuation

Chaque fois que vous accordez une autorisation en fonction d’adresses de courriel, commencez toujours la Rule par la logique suivante :
function (user, context, callback) {
  // L'accès ne doit être accordé qu'aux utilisateurs vérifiés.
  if (!user.email || !user.email_verified) {
    return callback(new UnauthorizedError('Access denied.'));
  }
Parfois, même un courriel vérifié peut ne pas être une vérification suffisante pour l’autorisation que vous souhaitez accorder. Pour en savoir plus sur ce type de cas, veuillez consulter Email Verified Usage.

Cette mise à jour aura-t-elle une incidence sur mes utilisateurs?

Cela ne touchera les utilisateurs existants que s’ils n’ont pas vérifié leur adresse de courriel.

Secrets en texte clair dans le code de Rule

Si vous incluez des renseignements sensibles, comme des clés API, dans le code de Rule, vous devriez plutôt configurer ces valeurs dans les paramètres de la Rule. Par exemple : const myApiKey = 'abcdefghijklmnopqrstuvwxyz'; Comme ces valeurs sensibles figurent dans le code de Rule, elles resteront non chiffrées dans nos systèmes et risquent d’être exposées.

Suis-je concerné ?

Si vos Rules contiennent des valeurs sensibles directement dans leur code, vous êtes concerné.

Mesures d’atténuation

Placez les valeurs sensibles dans la zone Settings de la section principale Rules de l’Auth0 Dashboard, puis accédez-y dans votre Rule à l’aide de ce qui suit : const myApiKey = configuration.myApiKey; Ainsi, toutes les valeurs sensibles seront chiffrées dans les systèmes d’Auth0, ce qui réduit le risque d’exposition.

Cette mise à jour aura-t-elle une incidence sur vos utilisateurs?

Cela n’aura aucune incidence sur vos utilisateurs.