En ce moment, je génère une chaîne de 25 caractères stockée dans la base de données qui ne peut être utilisée qu'une seule fois et expire 30 minutes après l'enregistrement de l'utilisateur.
http://example.com/security/activate/ZheGgUNUFAbui4QJ48Ubs9Epd
Je fais une recherche rapide de base de données et la logique est la suivante:
Si le compte n'est pas activé ET si l'e-mail n'a pas été vérifié ET que le code de validation est toujours valide, activez le compte, marquez l'adresse e-mail comme vérifiée et marquez le code de validation comme utilisé.
Par exemple, toutes les 72 heures, il vidait les codes de validation expirés et utilisés. C'est pour dire à l'utilisateur que le lien d'activation cliqué a expiré par exemple s'il regarde son email le lendemain et essaie le lien.
Dois-je inclure l'UUID de l'utilisateur dans l'URL? Dois-je inclure autre chose?
J'ai pensé à m'assurer que l'adresse IP sur le formulaire d'inscription correspond à l'adresse IP de la demande lorsque le lien d'activation est enfoncé, mais pour moi, je lis principalement mes e-mails sur mon téléphone portable pour ce genre de choses, donc ce serait pénible pour UX .
Comment générez-vous la chaîne de 25 caractères que vous incluez dans l'URL? Est-ce complètement aléatoire, ou est-il basé sur l'heure actuelle ou sur le courrier électronique des utilisateurs? Il doit être aléatoire et non devinable.
Vous devez vous assurer que la page de vérification s'affiche réellement (pas seulement qu'une demande GET s'est produite). Les navigateurs tels que chrome (et les programmes antivirus) chargent souvent les URL sans que l'utilisateur ne les clique explicitement en tant que prélecture ou pour des raisons de sécurité.
Cela pourrait entraîner un scénario où un acteur malveillant (Eve) souhaite créer un compte en utilisant le courrier électronique de quelqu'un d'autre (Alice). Eve s'inscrit et Alice reçoit un e-mail. Alice ouvre l'e-mail parce qu'elle est curieuse d'un compte qu'elle n'a pas demandé. Son navigateur (ou antivirus) demande l'URL en arrière-plan, activant le compte par inadvertance.
J'utiliserais JavaScript sur la page pour vérifier la page réellement affichée, et j'inclurais également un lien dans l'e-mail où les utilisateurs peuvent signaler qu'ils n'ont PAS créé ce compte.
Ajout à la réponse du Daisetsu (car je ne peux pas encore écrire de commentaires).
Il ne serait pas mauvais de créer un formulaire et de demander à l'utilisateur de créer un mot de passe. de cette façon, l'utilisateur devra entrer un nouveau mot de passe et après l'avoir soumis, le compte sera activé. Cela résoudrait la vérification antivirus en arrière-plan.
Quant à l'URL, cela devrait être suffisant tant qu'il s'agit d'une chaîne aléatoire. Il y a très peu de chances que vous ayez 2 clés du même contenu à la fois.
Vérifier l'IP ne serait pas bon car certains FAI peuvent faire pivoter les adresses IP afin que vous bloquiez quelqu'un qui veut s'enregistrer mais ne peut pas.
Votre e-mail doit inclure un code d'activation, pas un lien. Vous ne devez pas envoyer de lien utilisé pour la gestion de compte dans un e-mail. Si vous (la partie légitime) liez des courriers électroniques (en particulier avec de longues chaînes de caractères aléatoires) à des utilisateurs, il est alors un peu plus difficile de distinguer les courriers électroniques légitimes des tentatives de phishing.
Le code d'activation doit être composé de caractères qui peuvent être facilement copiés et collés (pas d'espaces, '+', '-', etc.) et qui sont également faciles à saisir manuellement. Les lettres et les chiffres fonctionnent. La sécurité du code d'activation dépend de son caractère imprévisible. Vous dérivez la valeur en utilisant le générateur de nombres aléatoires sécurisé du système, tout comme vous devriez le faire avec les ID de session pour les cookies.
Les codes d'activation doivent être stockés dans une table de base de données, chaque ligne avec un ID de profil, le code d'activation*et le délai d'expiration. Vous ne voulez pas mettre l'ID de profil ou le délai d'expiration dans un cookie, une URL ou le code d'activation.** Un utilisateur malveillant pourrait altérer l'ID pour reprendre un autre compte. Vous devez vérifier ces éléments côté serveur, car votre politique de sécurité ne peut pas faire confiance aux données client à l'aveuglette.
Le code d'activation doit être soumis via une demande POST. Redirigez automatiquement les utilisateurs vers l'URL d'activation du compte (qui peut simplement être https://example.com/security/activate
) lorsqu'ils ont terminé avec le reste de l'enregistrement. Facilitez à nouveau l'accès à la page d'activation du compte en cas de fermeture accidentelle.
Vous ne souhaitez pas qu'une requête GET effectue une action. Un lien peut être visité sans interaction de l'utilisateur (en raison de la prélecture du navigateur ou des services de sécurité des e-mails). De plus, le fait de mettre des secrets dans une URL peut entraîner une fuite de données sensibles. (Par le biais d'en-têtes de référence ou d'extensions de navigateur.)
Ne vous inquiétez pas de l'IP, elle peut encore changer. (Idem pour l'agent utilisateur.)
Je ne sais pas si une fonction d'annulation est souhaitable. Je n'utilise même pas les liens de désabonnement dans les e-mails non sollicités, car cela peut être un moyen de déterminer s'il existe ou non un humain associé à une adresse e-mail. Si le code d'activation est suffisamment long pour résister à la force brute ou si vous limitez le nombre de tentatives de code d'activation, je ne vois pas le mal à laisser le code d'activation expirer finalement.
En revanche, il pourrait être intéressant de réduire le nombre d'e-mails d'activation de compte indésirables. Vous pouvez limiter le nombre d'e-mails que vous envoyez à une adresse, pour être poli. Dites un maximum de 3 par jour et un maximum de 5 par mois. (Je ne sais pas si c'est trop élevé ou trop bas.) En tant que non-utilisateur, je ferais simplement des e-mails de votre site Web supprimés ou marqués automatiquement comme lus.
Il existe de nombreuses variables à prendre en compte pour les e-mails d'activation indésirables. Cela a probablement plus à voir avec l'expérience utilisateur qu'avec la sécurité. Vous pouvez aller jusqu'à proposer une fonction "annuler mon activation et ne jamais envoyer d'e-mails à cette adresse car je ne vais jamais m'enregistrer", mais cela pose des problèmes évidents. (Vous devez également vérifier l'e-mail de la personne également.)
* Cela ne fait pas de mal de hacher le code d'activation. Il n'est pas non plus essentiel de hacher, comme avec les mots de passe, car chaque code a une utilisation unique, ne contient aucune information privée, est généré de manière aléatoire par le serveur et expire.
** Vous pouvez réellement empêcher la falsification à l'aide d'un MAC cryptographique, mais je déconseille fortement d'essayer cela pour la plupart des développeurs. La cryptographie est difficile à réaliser correctement.
Comme pour tout domaine où vous utilisez des pratiques de sécurité, l'évaluation de l'exposition et des menaces est quelque chose que vous devrez évaluer pour votre environnement unique et votre cas d'utilisation. Les réponses existantes fournissent de nombreux points de contact pour cette évaluation, ainsi que des pointeurs à éviter, tels que des actions déclenchées par GET
. Au lieu de cela, je vais me concentrer davantage sur la partie "utilisateur" de l'UX. Je vais également aborder de nombreux commentaires éparpillés sur la page.
Exactement ce que vous "vérifiez" avec l'action déclenchée par e-mail est également un facteur à considérer. Si tout ce que vous faites est de confirmer qu'il s'agit d'une adresse e-mail valide, alors presque toute action sera suffisante. La vérification de l'e-mail, l'intention de créer le compte et que l'utilisateur qui reçoit l'e-mail est celui qui a initié la création du compte nécessite un peu plus d'efforts.
Un "effort" que vous ne devriez pas prendre, cependant, est l'envoi d'e-mails de rappel. En supposant que l'utilisateur a créé intentionnellement le compte, utilisé une adresse e-mail valide et souhaite utiliser le compte à quelque fin que ce soit que vous proposez, il recherchera l'e-mail et entreprendra le processus d'activation dès qu'il le pourra. Le lien, le code ou autre peut expirer avant de l'utiliser s'il est détourné sur d'autres sujets en attendant l'e-mail. Leur permettre de renvoyer l'e-mail de vérification dans de tels cas est très bien. Un e-mail de rappel, cependant, est beaucoup plus susceptible d'être un déclencheur de spam qu'un avantage pour l'utilisateur.
En tant qu'utilisateur, j'apprécie d'avoir des options disponibles pour activer/vérifier mon compte. Le jeu d'options le plus courant que j'ai rencontré est celui où l'e-mail fournit un lien sur lequel je peux cliquer ou couper et coller, et un code de confirmation que je peux entrer dans un champ de formulaire sur une page de mon zone de paramètres de compte sur le site Web. Le code de confirmation est rarement autre chose qu'un entier de 5 à 9 chiffres.
Les e-mails de vérification qui me donnent, en tant qu'utilisateur, le plus de confiance sont ceux qui ont un hachage crypto dans l'URL (/verify?l=lgGS2SBjMTU4NjkwNjYxMjI5MDBhZDk2YjEyMzMzYjNhZmQxOb
), ce qui m'amène à une page unique à moi où je dois ensuite entrer le mot de passe que j'ai utilisé pour créer le compte. L'utilisation du hachage confirme que le lien a été reçu dans un e-mail, non deviné ou forcé brutalement, vérifiant ainsi que l'e-mail est valide. La diffusion de cette page unique, avant toute autre action, permet au serveur de marquer l'e-mail auquel il a été envoyé comme "valide" sans confirmer la création du compte. La saisie du mot de passe confirme qu'il y a un acteur à l'autre extrémité, par opposition à une opération antivirus, de détection de logiciels malveillants ou de prélecture. La validité du mot de passe confirme, à un degré de certitude raisonnable, que le destinataire de l'e-mail et le créateur du compte sont la même personne.
Le délai proposé de 30 minutes semble un peu sévère, alors qu'une période de 24 heures pourrait être trop longue si votre évaluation de la menace suggère que votre exposition en 24 heures est inacceptable. Je crois que 2 heures devraient être suffisantes pour presque tous les environnements d'utilisateurs. Surtout si la possibilité de renvoyer la vérification est disponible. Même en utilisant un appareil mobile avec une connexion de 14 kb/s à un compte POP distant, vous devriez pouvoir terminer l'échange en 120 minutes.
L'utilisation de JS pour vérifier en quelque sorte les actions humaines peut être problématique. JS peut être désactivé, et est beaucoup plus souvent que de nombreux développeurs Web aimeraient savoir. Deuxièmement, les bloqueurs de publicités peuvent bloquer JS sur une base par site ou par source, même lorsque JS est activé dans le navigateur. Je bloque de nombreuses sources JS, y compris les scripts d'analyse de Google, sur une base globale, et j'en liste sur la liste blanche pour des sites, tels que Stack Exchange, où je suis prêt à les soutenir avec l'utilisation de mes données.
Inclure un lien dans l'e-mail, ou sur la page de confirmation, pour "annuler" le compte est un gaspillage. Dans l'e-mail, il est en fait contre-productif, c'est-à-dire que cliquer sur un lien concernant un compte que vous ne voulez pas est une bonne idée. Au lieu de cela, l'e-mail doit inclure un verbiage pour indiquer que ne rien faire entraînera la non-confirmation du compte et sa suppression. Un lien pour annuler sur la page de confirmation est encore pire, car il récompense un mauvais comportement. Je reçois fréquemment des e-mails, dans le cadre d'un ancien snafu Google, dirigés vers un autre compte Gmail, et je suppose que l'inverse est également vrai pour l'autre compte. [Dans le passé, Google ne fusionnait pas les noms d'utilisateurs pointillés et non pointés, donc mon nom d'utilisateur pointillé et la version non pointée de quelqu'un d'autre sont des comptes différents, mais Google glissera de temps en temps et j'obtiens quand même leur e-mail :(]
Le degré de couplage de l'adresse e-mail "vérifiée" avec le lien d'activation est fonction de votre cas d'utilisation et de l'évaluation des menaces. Je suis légèrement ennuyé lorsque je dois revalider mon compte après avoir changé l'adresse e-mail associée. La façon dont j'accepte le processus est proportionnelle à ma "valeur" du compte. Pour mon compte bancaire, Paypal, etc., j'accepte à 100%. Sur PcPartsPicker, cependant, j'accepterais environ 15% d'un tel processus.
Quant à l'IP et/ou l'agent utilisateur, ignorez-les. À titre d'exemple, je vais souvent consulter des sites et choisir de créer un compte à l'aide de mon appareil mobile. Je vais pas, mais ouvrir des e-mails dessus. Si je crée un compte et que j'apprends que je dois le vérifier ou le confirmer d'une manière ou d'une autre et que le courrier électronique est la méthode proposée, j'attendrai jusqu'à ce que je rentre chez moi pour ouvrir le courrier électronique sur mon bureau, où je pourrai l'inspecter. L'IP et l'agent utilisateur seront donc très différents. Mon mot de passe, cependant, restera le même, et cela devrait être suffisant pour me confirmer en tant que créateur du compte d'origine.
N'oubliez pas que les e-mails sont à peu près aussi sécurisés que le Jumbo-tron à Times Square, et procédez en conséquence.
Un e-mail de vérification nécessite peu de choses, à la fois pour être raisonnablement sûr et convivial:
GET
. Oui, les utilisateurs ne sont pas censés cliquer sur les liens, mais ils le feront quand même (vous n'allez pas les éduquer!). D'un autre côté, expérience utilisateur est beaucoup mieux que d'avoir à copier-coller une chaîne obscure.POST
s les données, cela garantit que le chargement spéculatif des URL ne laisse pas les choses se produire (involontairement ou même par malveillance) que l'utilisateur propriétaire du courrier l'adresse n'est pas connue. Le formulaire doit afficher une quantité raisonnable d'informations pour que l'utilisateur sache ce qui se passe et comme dernière chance de déclencher "WTF?" dans le cas où l'utilisateur n'a pas enregistrer ce compte.D'après votre question, je prends les hypothèses suivantes et si l'une d'entre elles n'est pas valide, ma réponse l'est également:
Dans ce cas, du point de vue de la sécurité, votre approche est tout à fait correcte. 25 caractères vous donnent suffisamment d'assurance contre les collisions aléatoires et les tentatives de force brute, l'utilisation unique protège contre le reniflement et les attaques similaires et de toute façon la seule chose que quelqu'un pourrait accomplir est d'activer un compte.
Vous voudrez peut-être inclure l'ID utilisateur si vous avez beaucoup d'utilisateurs pour des raisons de performances (MISE À JOUR: pas vraiment, voir les commentaires ci-dessous) La recherche de l'utilisateur par un jeton de chaîne entraînera une analyse de table, tandis que le trouver par ID, puis récupérer et comparer la chaîne est une recherche d'index. Cependant, cela expose l'ID utilisateur, que vous pouvez ou ne souhaitez pas faire.