[RESOLU] Stocker convenablement le mot de passe d'un compte mail

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : [RESOLU] Stocker convenablement le mot de passe d'un compte mail

Re: [RESOLU] Stocker convenablement le mot de passe d'un compte mail

par @rthur » 22 oct. 2024, 15:52

Pour un simple formulaire d'envoi d'emails, charger une librairie tierce pour lire un .env, c'est à mon sens overkill.

Techniquement, il n'y a aucun avantage, car ça revient exactement au même de lire un fichier .env ou un fichier .php en dehors de ton DocumentRoot.
Par contre, tu ajoutes un risque de sécurité et de la dette technique en chargeant une librairie tierce avec du code que tu ne maitrises pas.


En revanche, si ton projet est beaucoup plus ambitieux que ça, avec plusieurs développeurs qui travaillent dessus en parallèle, pourquoi pas.
Sinon, faire simple, c'est souvent la meilleure approche :)

Re: Stocker convenablement le mot de passe d'un compte mail

par kgdrenefort » 22 oct. 2024, 13:02

Merci pour ta réponse.
Une erreur de configuration qui rendrait la source de tes fichiers PHP lisible est extrêmement rare (mais pas impossible).
Si c'est possible, ça reste à considérer :).
La solution la plus classique est bien celle que tu as évoquée : le mettre en dur dans un fichier .php et ce fichier doit être en dehors du DocumentRoot pour ne pas pouvoir être appelé via une url.
Après plus de recherches, et je peux bien sûr me tromper, cela semble être une méthode un peu datée, j'ai trouvé comme autre solution des classes tel que PHPDotEnv (github: /vlucas/phpdotenv). Cela semble assez bien correspondre à mon besoin, notamment limiter les risques d'exposer certaines informations sensibles, même au delà du mot de passe j'imagine.
Pas sûr que ça ait un intérêt de mettre un cron pour envoyer par batch les emails d'un formulaire.
A mon sens l'envoi en direct au fil de l'eau est le plus répandu et fonctionne bien.
Cela fait partie du workflow qui est toujours en construction : Parmi toutes les manières d'éviter que ce formulaire ne puisse être abusé pour:

1/ Sur-charger une boîte mail (le destinataire)
2/ Se faire bloquer l'accès au serveur SMTP de son ESP
3/ Se faire emmerder

J'ai notamment mis en place une liste d'attente : Ces mails, à destination d'une association, ne sont pas « en retard » si un délais de 5 minutes est mis en place. Cela permet même en cas d'abus du formulaire (même moi peux assez rapidement concevoir un outil qui va automatiser le bourrage du formulaire), de ne recevoir qu'un mail toutes les X minutes.

Si je me retrouve avec 100 mails en attente, certes cela prendrais 5 minutes × 100 = 500 minutes (soit 8,3 heures). Cela n'est pas réaliste au vu de nos réceptions actuel de mails. Si ça arrive, je pourrais aussi assez rapidement le savoir via une sonde pour monitorer.

Donc non ce n'est pas une vrai sécurité contre le spam ou le flood du formulaire, mais en cas de problème, notre boîte mail reste 100% utilisable et on est pas non plus interdit chez notre ESP.
Par ailleurs, si ton formulaire est accessible publiquement (sans identification) il faut que tu prévois de filtrer les données en fonction de leur contenu (et/ou mettre un captcha) pour éviter que des robots spammeurs qui remplissent automatiquement les formulaires dispo sur le web pour envoyer des liens vers des sites douteux.
C'est effectivement ce qui est prévu, mon délais pour l'envoi de mail permet juste en cas de succès d'un attaquant, de limiter la casse.

À l'heure actuelle, il n'y a pas de captcha, mais je prévois la mise en place de :

- Un captcha, qui doit être raisonnablement lisible (l'association est centré autour des troubles du neurodéveloppement… dont les troubles DYS… et pour eux les captcha c'est infernal). Je pourrais le cas échéant remplacer ça par une question auquel on répond, c'est basique et pas mieux ou moins bien qu'un captcha, sauf que ce dernier peut être unique à chaque fois, la question elle… je vois difficilement comment.

- Un honey pot pour capter les bots trop bêtes pour s'en rendre compte sans gêner les utilisateurs.

- Éventuellement, la mise en place de filtres via des outils du type RSpamD qui vont analyser le contenu à la recherche de choses suspecte. Les termes "hot", "girls", "area" sont pas le genre de choses que l'on rencontre dans nos échanges par e-mail ;).

- Ou encore un outil du style "Êtes-vous un humain" qui analyse les mouvements de la souris, mais ça servira pas longtemps contre les outils propulsé par IA d'ici quelques temps, j'imagine.

Cependant, merci pour ta réponse, qui correspond à ma question initiale.

Pour l'heure je considère le sujet comme résolu : Je vais tester PHPDotenv et, si ça ne convient pas, voir cette méthode plus classique.

Cordialement,
GASPARD DE RENEFORT Kévin

Re: Stocker convenablement le mot de passe d'un compte mail

par @rthur » 22 oct. 2024, 12:23

Bonjour et bienvenue sur PHPfrance,

Une erreur de configuration qui rendrait la source de tes fichiers PHP lisible est extrêmement rare (mais pas impossible).

La solution la plus classique est bien celle que tu as évoquée : le mettre en dur dans un fichier .php et ce fichier doit être en dehors du DocumentRoot pour ne pas pouvoir être appelé via une url.


Pas sûr que ça ait un intérêt de mettre un cron pour envoyer par batch les emails d'un formulaire.
A mon sens l'envoi en direct au fil de l'eau est le plus répandu et fonctionne bien.

Par ailleurs, si ton formulaire est accessible publiquement (sans identification) il faut que tu prévois de filtrer les données en fonction de leur contenu (et/ou mettre un captcha) pour éviter que des robots spammeurs qui remplissent automatiquement les formulaires dispo sur le web pour envoyer des liens vers des sites douteux.

Stocker convenablement le mot de passe d'un compte mail

par kgdrenefort » 22 oct. 2024, 10:52

Bonjour,

- Version de PHP: 8.2
- Système d'exploitation du serveur: Linux
- Serveur web: NGinX
- Framework: Aucun
Classe externes: PHPMailer

mon premier message ici, fraîchement inscrit, car je suis un peu perdu.

Contexte: Je me forme au PHP en autodidacte depuis à peine quelques semaines et mon projet présentement consiste au développement d'un formulaire d'envoi de mail vers le compte mail d'une association dans laquelle je suis.

Pour cela, j'ai crée un ensemble de fonctions et j'ai le corps principale de mon code qui m'autorise à :

- Recevoir depuis un formulaire HTML des données entrées par l'utilisateur, envoyé via la méthode $_POST.

- Ces données sont reçu par un script dont l'unique but est de déterminer si les données entrées sont valides : Tailles des chaînes, analyse des entrées (pattern matching) pour savoir si quelqu'un tenterait pas d'entrée au mieux des données incorrectes, au pire des tentatives de piratages.

- Une fois que tout est validé (sinon ça exit), ces données sont stockés temporairement dans un répertoire de mails en attente.

- Une tâche cron doit passer toutes les X minutes, récupérer le plus vieux fichier / mail et essaye de l'envoyer via PHPMailer.

- Une fois terminé, selon le statut renvoyé par PHPMailer, le fichier / mail est déplacé dans un répertoire ACCEPTED or REJECTED, à titre de logs.

Cela fonctionne, j'utilise le serveur SMTP de mon ESP via un compte, en IMAP. Les mails parviennent bien à destination !

Par contre, stocker dans un fichier .php en dur les données du serveur SMTP de mon ESP, particulièrement utilisateur / mot de passe c'est bien entendu tout pourri. C'était à titre de test.

Maintenant, j'aimerai être sûr que ce code ne contienne pas la moindre traces de données qui n'ont rien à y faire.

Après quelques recherches et questions posées par-ci par-là, j'en suis arrivé à la conclusion qu'une bonne méthode serait de :

1/ Stocker ces données dans un fichier (car mon application ne se repose pas sur une base de donnée) qui n'est pas accessible via le navigateur. Le nommer .php pourrait suffire, mais une simple erreur de configuration de PHP et on télécharge le .php au lieu de l'exécuter, c'est pas suffisant.

2/ Ce fichier doit être en dehors du DocumentRoot, car même si je demande explicitement au serveur web de ne pas accepter de requête, une erreur de configuration encore une fois et…

3/ Rendre ce fichier uniquement accessible par PHP, son utilisateur, mais personnes d'autres.

En gardant en tête qu'un mot de passe d'une boîte mail n'est pas l'information la plus sensible qui soit, qu'en cas d'accès non désiré à mon serveur j'aurai sûrement autre chose de plus important que ce compte mail à protéger… compte mail auquel j'ai les accès chez mon ESP et que je peux modifier/supprimer/bloquer à ma guise. Cependant, si on pouvait éviter que le tout venant puisse consulter ces informations… c'est mieux.

Au début, je pensais que je pouvais sûrement chiffrer le fichier contenant le mot de passe et le déchiffrer à la volée via ce genre de fonctions dans la doc de php dot net: manual/en/book.password.php

Mais on m'a gentiment expliqué que c'était pas fondamentalement utile : Puisque la clé servant à déchiffrer le fichier est de toute façon accessible au serveur, donc en cas d'intrusion… ce fichier l'est sûrement aussi. Et comme, bien sûr, tout doit fonctionnement sans rien faire, je ne peux pas manuellement taper de mot de passe pour utiliser une clé qui déchiffrerait le fichier, ça ne fait pas sens.

Auriez-vous des suggestions concernant ce cas ?

Ma crainte principale serait de pouvoir consulter ce fichier, de manière indésiré, via une requête ou un oubli dans ma configuration (ce qui ne doit jamais arrivé, bien sûr, mais je préfère imaginer que ça arrivera et ajouter des couches).

Cordialement,
GASPARD DE RENEFORT Kévin