Bulletin de sécurité pour les règles Auth0
Date de publication : 10 janvier 2019
Présentation
Ce bulletin de sécurité couvre plusieurs scénarios que les clients doivent éviter dans le code de règle personnalisée, car ils peuvent créer des vulnérabilités dans le flux d’authentification. Une description de chaque problème et, dans la mesure du possible, une autre façon d’écrire la même règle, sont fournies ci-dessous.
Du code de règle personnalisée, contenant une logique conditionnelle pour appliquer l’authentification multifacteur (MFA), menace la bonne application de la MFA, en particulier en mode d’authentification silencieuse.
Un code de règle personnalisée mettant en œuvre des contrôles d’autorisation en fonction d’une sous-chaîne spécifique sans logique appropriée peut entraîner des privilèges élevés.
Custom rule code sending diagnostic information to third-party services, rather than using Auth0’s built-in debugging features, may result in sensitive information disclosure.
Un code de règle personnalisée déclenchant des services payants peut permettre à une personne malveillante d’engager des frais de facturation non désirés.
Un code de règle personnalisée accordant une autorisation sur la base d’adresses courriel non vérifiées peut permettre à des personnes malveillantes d’acquérir ces privilèges par le biais d’un type de connexion secondaire.
Un code de règle personnalisée 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’exposition de ces secrets.
Règles MFA inappropriées
Authentification silencieuse
Dans une application monopage (SPA), l’authentification silencieuse permet d’émettre de nouveaux jetons d’accès sans interaction de l’utilisateur tant que la session en cours est valide par rapport au serveur d’autorisation.
Auth0 offre une authentification silencieuse par le biais d’un paramètre spécial qui est ajouté au point de terminaison d’autorisation comme suit :
/authorize?prompt=none
Toutefois, si la MFA est ajoutée au processus d’authentification silencieuse, l’interaction avec l’utilisateur devient nécessaire.
La logique conditionnelle basée sur l’authentification silencieuse pour contourner la MFA ne doit pas être utilisée comme solution de contournement. Les règles de ce type permettent de contourner complètement la MFA et ne doivent pas être utilisées :
function (user, context, callback) {
if (context.request.query && context.request.query.prompt === 'none') {
// skip MFA for silent token requests
return callback(null, user, context);
}
...
}
Was this helpful?
Authentification silencieuse avec redirection vers un fournisseur MFA personnalisé
Les règles qui déterminent si la redirection vers l’authentification multifacteur (MFA) personnalisée basée sur l’authentification silencieuse peut permettre de contourner la MFA dans certaines circonstances inhabituelles. Par exemple, évitez les situations suivantes :
function (user, context, callback) {
if (context.request.query && context.request.query.prompt === 'none') {
//redirect to custom MFA
context.redirect = {
url: "https://example.com/"
};
...
}
Was this helpful?
Vérification incorrecte
L’utilisation de règles pour contourner l’authentification multifacteur (MFA) dans des conditions spécifiques peut permettre de contourner la MFA lorsque les vérifications en place sont inadéquates pour déterminer la véracité d’un état souhaité.
Dans ces cas, le problème réside dans le fait que les règles ne peuvent en aucun cas déterminer si la MFA a été exécutée avec succès, car celle-ci se produit une fois la règle exécutée. Les règles configurées de cette manière (voir les exemples ci-dessous) mettent à jour prématurément l’enregistrement de l’utilisateur en supposant, à tort, que la MFA sera exécutée avec succès, tout en s’appuyant sur le même enregistrement de l’utilisateur pour ignorer la MFA dans des conditions données.
Les exemples ci-dessous illustrent des vérifications incorrectes qui peuvent entraîner un contournement complet de l’authentification multifacteur (MFA).
Empreinte digitale de l’appareil
function (user, context, callback) {
var crypto = require('crypto');
var deviceFingerPrint = getDeviceFingerPrint();
user.app_metadata = user.app_metadata || {};
// Inadequate verification check
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');
}
}
Was this helpful?
Indicatif de pays
function (user, context, callback) {
user.app_metadata = user.app_metadata || {};
// Inadequate verification check
if (user.app_metadata.last_location !== context.request.geoip.country_code) {
user.app_metadata.last_location = context.request.geoip.country_code;
context.multi-factor = {
...
};
}
Was this helpful?
Cela me concerne-t-il?
Si vous utilisez l’une des logiques de règles illustrées précédemment, une personne malveillante qui s’est connectée avec succès à l’aide du premier facteur d’authentification peut être en mesure de contourner la MFA sur votre application.
Mesures d’atténuation
Si vous êtes concerné par le scénario d’authentification silencieuse, supprimez la logique conditionnelle basée sur prompt === ’none’
. Cela déclenchera l’authentification multifacteur (MFA) à chaque appel d’authentification silencieuse pour vérifier l’état de la session.
Si vous êtes concerné par le scénario d’authentification silencieuse avec redirection, supprimez la logique conditionnelle basée sur prompt === ’none’
et passez à un fournisseur d’authentification multifacteur pris en charge par Auth0.
Pour éviter de demander trop souvent à l’utilisateur d’utiliser l’authentification multifacteur, vous pouvez définir le paramètre allowRememberBrowser
sur true, ce qui permettra aux utilisateurs finaux de cocher une case de sorte à ne recevoir une invite à l’authentification multifacteur (MFA) que tous les 30 jours. Par exemple :
context.multi-factor = {
provider: 'guardian',
allowRememberBrowser: true
};
Was this helpful?
Vous pouvez informer vos utilisateurs finaux qu’ils doivent cocher la case pour éviter de recevoir des invites trop fréquemment.
Si vous êtes concerné par des règles utilisant une vérification incorrecte pour ignorer la MFA, assurez-vous d’utiliser des vérifications solides, d’interrompre complètement les exceptions MFA ou d’utiliser l’option de configuration a allowRememberBrowser
décrite ci-dessus.
Cette mise à jour aura-t-elle des répercussions sur mes utilisateurs?
Selon la façon dont vous adaptez vos règles ou votre configuration, cette mise à jour peut avoir des répercussions sur vos utilisateurs en les invitant à utiliser la MFA plus souvent qu’à l’accoutumée.
Vérification incorrecte des sous-chaînes
Si vous avez une logique de règle qui exige un contrôle d’accès en fonction d’une correspondance exacte à une chaîne particulière, comme un domaine de messagerie, mais que vous vérifiez seulement une sous-chaîne au lieu d’une correspondance exacte, votre logique risque de ne pas fonctionner comme prévu. Par exemple :
if( _.findIndex(connection.options.domain_aliases,function(d){ return user.email.indexOf(d) >= 0;
La logique ci-dessus renvoie des courriels tels que :
user.domain.com@not-domain.com
"user@domain.com"@not-domain.com
(guillemets inclus)
Cela me concerne-t-il?
Seuls les clients utilisant la logique conditionnelle dans les règles, comme décrit ci-dessus, sont concernés.
Mesures d’atténuation
Utilisez une logique telle que :
const emailSplit = user.email.split('@'); const userEmailDomain = emailSplit[emailSplit.length - 1].toLowerCase();
Pour plus d’informations, reportez-vous au modèle de règle Vérifier les domaines par rapport aux alias de connexion. Vous pouvez également, dans la section Règles de Auth0 Dashboard, afficher le modèle de règle intitulé Vérifier si le domaine de messagerie de l’utilisateur correspond au domaine configuré.
Cette mise à jour aura-t-elle des répercussions sur mes utilisateurs?
Probablement. La modification recommandée pour les règles dont la logique est basée sur des vérifications de sous-chaînes peut avoir un impact sur les utilisateurs finaux, même s’il vous incombe de déterminer l’intention de vos règles et si les modifications recommandées sont susceptibles d’avoir un impact sur vos utilisateurs finaux.
Débogage à l’aide de services externes
Si vous avez une logique de règle qui envoie l’objet de contexte Auth0 à un service externe, vous exposez des éléments tels que id_token
ou access_token
associés à la demande. 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);
});
Was this helpful?
Cela me concerne-t-il?
Seuls les clients dont la logique des règles est décrite ci-dessus sont concernés.
Mesures d’atténuation
Vous devez modifier votre règle 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. À la place, vous devez envoyer un sous-ensemble d’attributs de l’objet de contexte qui sont moins sensibles.
Pour plus d’informations, veuillez vous référer au modèle de règle Requestbin. Vous pouvez également, dans la section Règles d’Auth0 Dashboard, afficher le modèle de règle intitulé Vider les variables de la règle dans RequestBin.
Auth0 propose également des méthodes intégrées pour déboguer les règles sans envoyer d’informations à des services externes.
Cette mise à jour aura-t-elle des répercussions sur mes utilisateurs?
Non. La règle impactée était le plus souvent utilisée à des fins de débogage. Cette modification ne devrait pas avoir d’incidence sur les utilisateurs finaux.
Règles d’utilisation d’un service payant
Si vous avez une logique de règles qui implique un service payant, tel que l’envoi de messages SMS via Twillio, dans le cadre du processus d’authentification, vous pourriez être vulnérable à une augmentation des coûts car une personne malveillante disposant d’un nom d’utilisateur et d’un mot de passe valides pourrait être en mesure de déclencher un appel au service et d’engager des coûts sans avoir à suivre l’ensemble du processus d’authentification spécifié par les règles. Par exemple :
//Sends user SMS 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);
});
}
Was this helpful?
Cela me concerne-t-il?
Seuls les clients disposant d’une logique de règles telle que décrite ci-dessus, et dont la logique de règles peut être déclenchée par un utilisateur non autorisé, sont concernés.
Mesures d’atténuation
Pour atténuer ce risque, envisagez une ou plusieurs des actions suivantes :
Interdire les inscriptions publiques, si elles ne sont pas strictement nécessaires, afin de réduire le nombre d’utilisateurs qui peuvent s’inscrire et déclencher des appels à des services payants.
Atténuer le risque de vol d’informations d’identification afin d’éviter la prise de contrôle de comptes par des pirates qui pourraient utiliser des comptes piratés pour déclencher des appels à des services payants.
Veiller à ce que vos utilisateurs utilisent des mots de passe robustes lorsqu’ils se connectent à des bases de données.
Veiller à ce que vos utilisateurs utilisent l’authentification multifacteur (MFA).
Veiller à ce que la règle ne soit 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 possède un domaine de messagerie, 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 des répercussions sur mes utilisateurs?
Les répercussions sur les utilisateurs finaux dépendent de l’option décrite ci-dessus que vous choisissez pour atténuer le problème.
Autorisation basée sur une adresse courriel non vérifiée
Si vous avez une logique de règles qui exige un contrôle d’accès basé sur une adresse électronique particulière ou un domaine de messagerie, sans vérifier si l’utilisateur a vérifié son adresse électronique, un adversaire pourrait potentiellement 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;
});
Was this helpful?
La logique ci-dessus renverrait true
si une personne malveillante créait un compte en utilisant un type de connexion différent (par ex., une connexion par réseau social) avec une adresse courriel présente dans la liste d’autorisations. Cela se produit parce que la même adresse peut exister dans différents types de connexion.
Cela me concerne-t-il?
Seuls les clients qui utilisent la logique conditionnelle dans les règles décrites ci-dessus et qui autorisent plusieurs types de connexion sont concernés.
Mesures d’atténuation
Lorsque vous accordez une autorisation sur la base d’adresses courriel, commencez toujours la règle par la logique suivante :
function (user, context, callback) {
// Access should only be granted to verified users.
if (!user.email || !user.email_verified) {
return callback(new UnauthorizedError('Access denied.'));
}
Was this helpful?
Parfois, même une adresse courriel vérifiée peut ne pas constituer une vérification adéquate pour l’autorisation que vous souhaitez effectuer. Pour en savoir plus sur ces cas, consultez la rubrique Utilisation vérifiée d’une adresse courriel.
Cette mise à jour aura-t-elle des répercussions sur mes utilisateurs?
Cette mesure n’affectera que les utilisateurs existants qui n’ont pas vérifié leur adresse courriel.
Secrets en clair dans le code de la règle
Si vous spécifiez des informations sensibles (comme des clés API) dans le code de la règle, vous avez plutôt intérêt à configurer ces valeurs dans les paramètres de la règle. Par exemple :
const myApiKey = 'abcdefghijklmnopqrstuvwxyz';
Ces valeurs sensibles, présentes dans le code de la règle, resteront non chiffrées dans nos systèmes et risquent d’être exposées.
Cela me concerne-t-il?
Si vos règles contiennent des valeurs sensibles dans le code de la règle elle-même, vous êtes concerné.
Mesures d’atténuation
Placez les valeurs sensibles dans la zone Paramètres de la section principale Règles d’Auth0 Dashboard, puis accédez-y dans votre règle comme suit :
const myApiKey = configuration.myApiKey;
This will ensure that all sensitive values are encrypted within Auth0’s systems, reducing the risk of exposure.
Cette mise à jour aura-t-elle des répercussions sur mes utilisateurs?
Cela n’aura aucune répercussion sur vos utilisateurs.