Project

General

Profile

Evolution #1516

Renforcer sécurité pour la page d'inscription

Added by Nicolas Béhier-Dévigne 2 months ago. Updated 2 months ago.

Status:
Fermé
Priority:
Normal
Category:
Security
Target version:
Start date:
11/07/2020
Due date:
% Done:

100%

Estimated time:
Vote:

Description

Bonjour,
La page publique d'inscription des nouveaux adhérents /subscribe ne semble pas suffisamment sécurisée. Malgré le mot de passe à recopier depuis une image, nous avons 5 à 10 inscriptions de robots chaque jour depuis plusieurs mois.
Bonne journée, Nicolas.


Files

#1

Updated by Johan Cwiklinski 2 months ago

  • Project changed from Documentation to Galette

Je suis tout à fait pour ; mais je n'ai pas vraiment de solution pour ça. La majorité des recherches dans ce domaine mènent à une seule et unique solution que je ne veux pas utiliser...

Toute piste serait la bienvenue.

#2

Updated by Nicolas Béhier-Dévigne 2 months ago

J'imagine que tu penses aux solutions de Google ou Wordpress : Recaptcha ou Akismet.
Il y a aussi la solution du "HoneyPot" : https://www.mistersize.com/blog/contact-spam-honeypot-wordpress/

Je pense que de mon côté, je vais ajouter "simplement" une question du type "Quelle est la couleur de notre logo ?" ou "Quelle est la ville principale de notre Métropole ?"... et vérifier côté controller la réponse. Je ne pense pas réussir à le faire "proprement" et pour l'ensemble de la communauté. Mais si je trouve la solution, souhaites-tu que je le pousse sur une branche GIT ?

Bonne journée, Nicolas.

#3

Updated by Nicolas Béhier-Dévigne 2 months ago

Pour info, pour le moment j'ai fait un patch sur notre site :

  • création de templates/default/forms_types/captchaZDT.tpl
        {extends file="forms_types/input.tpl"}
    
        {block name="component"}
            {assign var="type" value="text"}
            {assign var="value" value=null}
            {assign var="label" value={_T string="Filtre anti-spam:"}}
            {assign var="example" value={_T string="Quelle est la ville principale de la Métropole ?"}}
            {assign var="tip" value={_T string="Cette question permet de minimiser l'effet des robots spammers"}}
            {assign var="required" value=true}
            {assign var="name" value="checkZDT"}
            {assign var="id" value="checkZDT"}
            {$smarty.block.parent}
        {/block}
    
  • ajout à ligne 131 dans templates/default/forms_types.tpl
        {if $self_adh and $fieldset@last}
            {include file="forms_types/captchaZDT.tpl"}
        {/if}
    
  • ajout ligne 1524 dans lib/Galette/Controllers/Crud/MembersController.php
        //check ZDT Captcha
        if (isset($args['self'])) {
            if (
                !$post['checkZDT']
                || strtoupper(trim($post['checkZDT'])) != 'TOURS'
            ) {
                $error_detected[] = __('Votre réponse anti-spam semble incorrecte');
            } else {
                unset($post['checkZDT']);
            }
        }
    
  • ajout ligne 1309 dans lib/Galette/Entity/Adherent.php
        case 'checkZDT':
            if (
                $this->_self_adh === true
                && (!isset($values['checkZDT']) || strtoupper(trim($values['checkZDT'])) != 'TOURS')
            ) {
                $error_detected[] = __('Votre réponse anti-spam semble incorrecte');
            }
    

Ce qui nous donne le fichier joint.
Pour bien faire, il faudrait que cette question/réponse se trouve dans l'onglet sécurité de /preferences.

#4

Updated by Johan Cwiklinski 2 months ago

Nicolas Béhier-Dévigne a écrit (#note-2):

J'imagine que tu penses aux solutions de Google ou Wordpress : Recaptcha ou Akismet.

Ouaip, ou même à une alternative open source que j'ai vue (Friendly Captcha), mais qui nécessite un compte cloud ou d'héberger la partie serveur.

Il y a aussi la solution du "HoneyPot" : https://www.mistersize.com/blog/contact-spam-honeypot-wordpress/

Oui, mais à priori ; ce n'est vraiment pas terrible pour l'accessibilité ce genre de solutions :(

Je pense que de mon côté, je vais ajouter "simplement" une question du type "Quelle est la couleur de notre logo ?" ou "Quelle est la ville principale de notre Métropole ?"... et vérifier côté controller la réponse. Je ne pense pas réussir à le faire "proprement" et pour l'ensemble de la communauté. Mais si je trouve la solution, souhaites-tu que je le pousse sur une branche GIT ?

Cette solution requiert une configuration côté utilisateur qui ne sera soit pas faite du tout, soit pas forcément de manière optimale. Prenons par exemple les questions que tu évoques :

  • "Quelle est la couleur de notre logo ?" => quid des déficients visuels ?
  • "Quelle est la ville principale de notre Métropole ?" => je ne peux pas y répondre personnellement :-)

Il faut donc pouvoir trouver une question à laquelle tout le monde puisse répondre, ce qui n'est pas forcément évident. Sans compter non plus qu'il faudrait en sus gérer les traductions.
Ça risquerait du coup d'être "trop efficace" (un peu l'effet de ces images de captcha plus illisibles les unes que les autres :D).

j'avais déjà réfléchi au sujet avant qu'une issue soit ouverte, je me doutais bien que le "captcha" d'origine ne tiendrait pas (c'est une pièce entièrement rapportée de Galette 0.6x :p) ; j'ai également envisagé des opérations arithmétiques simples (par exemple http://paste.alacon.org/) ; d'autant que je peux automatiser les locales :

php > $nf = new NumberFormatter('fr_FR', NumberFormatter::SPELLOUT);
php > echo $nf->format(45);
quarante-cinq
php > $nf = new NumberFormatter('en_EN', NumberFormatter::SPELLOUT);
php > echo $nf->format(45);
forty-five

Qu'en penses-tu ?

#5

Updated by Nicolas Béhier-Dévigne 2 months ago

Effectivement ta proposition d'opérations arithmétiques simples serait une meilleure alternative que la mienne, car ne nécessiterait pas le paramétrage en administration… En plus du point soulevé sur l’internationalisation. Très bonne idée donc.
Par contre, je ne pense pas pouvoir l'implémenter de mon côté, ou en tout cas pas à court terme.

#6

Updated by Johan Cwiklinski 2 months ago

  • Category set to Security
  • Assignee set to Johan Cwiklinski
  • Target version set to 0.9.5

Nicolas Béhier-Dévigne a écrit (#note-5):

Effectivement ta proposition d'opérations arithmétiques simples serait une meilleure alternative que la mienne, car ne nécessiterait pas le paramétrage en administration… En plus du point soulevé sur l’internationalisation. Très bonne idée donc.
Par contre, je ne pense pas pouvoir l'implémenter de mon côté, ou en tout cas pas à court terme.

Pas de soucis, je vais probablement m'en charger, et ça ne devrait pas être super compliqué non plus (enfin... avec de la chance).

Vu que je ne peux pas vraiment "reproduire", il faudra que tu fasse office de cobaye ;p

#7

Updated by Nicolas Béhier-Dévigne 2 months ago

Oh super !
Et pas de soucis pour faire office de cobaye… mais je ne pourrai y répondre qu'en mettant en prod et en attendant 2-3 jours la réaction des robots :-)

#8

Updated by Guillaume AGNIERAY 2 months ago

Johan Cwiklinski a écrit (#note-4):

Nicolas Béhier-Dévigne a écrit (#note-2):

Il y a aussi la solution du "HoneyPot" : https://www.mistersize.com/blog/contact-spam-honeypot-wordpress/

Oui, mais à priori ; ce n'est vraiment pas terrible pour l'accessibilité ce genre de solutions :(

+1 pour le honeypot :)

Quand il est bien réalisé, ça ne pose aucun problème d'accessibilité :
https://www.w3.org/TR/turingtest/#honeypots

Johan Cwiklinski a écrit (#note-4):

Il faut donc pouvoir trouver une question à laquelle tout le monde puisse répondre, ce qui n'est pas forcément évident. Sans compter non plus qu'il faudrait en sus gérer les traductions.
Ça risquerait du coup d'être "trop efficace" (un peu l'effet de ces images de captcha plus illisibles les unes que les autres :D).

j'avais déjà réfléchi au sujet avant qu'une issue soit ouverte, je me doutais bien que le "captcha" d'origine ne tiendrait pas (c'est une pièce entièrement rapportée de Galette 0.6x :p) ; j'ai également envisagé des opérations arithmétiques simples (par exemple http://paste.alacon.org/) ; d'autant que je peux automatiser les locales :
[...]

Qu'en penses-tu ?

Si je peux apporter mon grain de sel, je trouve que c'est la solution la plus performante lorsque des mesures moins intrusives ne suffisent plus.
Et par expérience, un simple calcul semble effectivement plus efficace qu'une image :)

Mais, il ne faut pas se leurrer, lutter contre les robots et le spam des formulaires c'est le jeu permanent du chat et de la souris.
Même les solutions SaaS et le recaptcha ne sont pas infaillibles.

Au boulot, je cumule toujours plusieurs solutions.
D'abord des solutions qui ne nécessitent pas l'interaction de l'utilisateur : honeypot, proof of work, test du support javascript.
Et seulement quand ça ne suffit plus, un captcha arithmétique.

Je peux parler de Drupal qui est le CMS que je connais le mieux.
Sur chaque projet mettant en œuvre des formulaires, j'installe généralement d'abord ces 2 modules :

Le premier n'affiche les formulaires que si le javascript est supporté (et sinon un message informant l'utilisateur qu'il doit activer le javascript dans son navigateur pour utiliser le formulaire).

Le second offre un honeypot paramétrable (pour pouvoir changer l'id du champ caché quand les robots le contournent), ainsi qu'un POW lui aussi paramétrable (en l'occurence, un temps minimum pour remplir le formulaire).

Et quand tout ça ne suffit plus, j'installe (en plus) un captcha arithmétique :

En cumulant ces 3 mesures préventives, ça permet de réduire significativement le spam.
Mais ça ne permet pas de l'éradiquer totalement :/

#9

Updated by Johan Cwiklinski 2 months ago

Guillaume AGNIERAY a écrit (#note-8):

+1 pour le honeypot :)

Quand il est bien réalisé, ça ne pose aucun problème d'accessibilité :
https://www.w3.org/TR/turingtest/#honeypots

La question que j'ai vue posée était me semble-t-il relative à la manière dont les lecteurs écran par exemple vont traiter ça. Avec une "question" ce point est bien plus clair.
Ça manque un peu de détails pour le coup sinon :/

Si je peux apporter mon grain de sel, je trouve que c'est la solution la plus performante lorsque des mesures moins intrusives ne suffisent plus.

Alors, moins intrusives : tout est relatif. L'actuel captcha (on part tout de même de là), ce n'est pas franchement moins "intrusif" qu'une question quelconque.

Et par expérience, un simple calcul semble effectivement plus efficace qu'une image :)

Oui, et plus confortable à l'usage aussi - en ce qui me concerne en tous cas. Je préfère nettement répondre à "combien font 10-2" que de chercher comme un gland les passages piétons sur des photos floues ou de recopier des mots à base de lettres "destroy" et qui n'ont souvent pas de sens :D

Mais, il ne faut pas se leurrer, lutter contre les robots et le spam des formulaires c'est le jeu permanent du chat et de la souris.
Même les solutions SaaS et le recaptcha ne sont pas infaillibles.

Ce n'est clairement pas le but ; d'autant qu'il ne s'agit pas du même niveau d'intérêt que sur des forums de discussion par exemple (là, c'est juste horrible).

Au boulot, je cumule toujours plusieurs solutions.
D'abord des solutions qui ne nécessitent pas l'interaction de l'utilisateur : honeypot, proof of work, test du support javascript.

Alors, les solutions javascript, c'est non :p
Galette reste à l'heure actuelle utilisable avec javascript désactivé ; hormis quelques rares parties de l'administration (pas pour les "simples adhérents" donc) ; c'est un coup à introduire des bugs potentiels (sur mises à jour navigateurs etc) qui n'existeraient pas sinon.

En plus, vu que le JS c'est vraiment pas mon truc, je suis bien plus à l'aise techniquement avec une solution "PHP only" :-)

Et seulement quand ça ne suffit plus, un captcha arithmétique.

Le "quand ça ne suffit plus" ici est fonction de l'instance sur laquelle je n'ai aucun contrôle, et doit donc être déterminé par « la personne en charge de Galette », qui se trouve être souvent en milieu associatif quelqu'un qui n'a pas forcément de compétences techniques en informatique.

Vu que de toutes façons je ne suis pas vraiment en mesure de tester/reproduire, passer directement sur l'option la plus sécuritaire me semble un bon choix.
De plus, c'est techniquement plus compliqué de cumuler différentes solutions, et c'est davantage de code à maintenir dans le temps :)

J'en retiens que sous semblons tous en accord sur l'efficacité de la solution «à la con» © :p - j'y travaille, et je vous fais signe ;-)

#10

Updated by Michel Verdier 2 months ago

Nous n'avons pas été confronté au problème, mais a priori je suis plus favorable à une question genre calcul, quitte à remplacer les signes par des mots.
( galette.leclub404.com )

#11

Updated by Johan Cwiklinski 2 months ago

Dans l'idée (ça semble être ce qui est fait sur pastealacon) : on aurait 2 opérandes prenant une valeur de 0 à 12 , et uniquement des additions et des soustractions.

Pour les additions, on piocherait dans les constructions de phrases suivantes :

  • How much is %1$s plus %2$s? (Combien font %1$s plus %2$s ?)
  • How much is %1$s added to %2$s? (Combien font %1$s ajoutés à %2$s ?)
  • I have %1$s Galettes, a friend give me %2$s more. How many Galettes do I have? :p

Pour les soustractions :

  • How much is %1$s minus %2$s? (Combien font %1$s moins %2$s ?)
  • How much is %1$s on which we retire %2$s? (Combien font %1$s à qui l'on retranche %2$s ?)
  • How much is %2$s retired to %1$s? (Combien font %2$s retranchés de %1$s ?)
  • I have %1$s Galettes, I give %2$s of them. How many Galettes do I have? :p

Les variables %1$s et %2$s seront remplacées respectivement par les parties gauche et droite de l'opération (qui vaudra donc soit %1$s + %2$s, soit %1$s - %2$s). Chaque chargement de page change les deux opérandes et l'opérateur lui même, chaque affichage prend une chaîne au "hasard".

#12

Updated by Johan Cwiklinski 2 months ago

Un tout premier jet de ce à quoi ça pourrait ressembler :
https://github.com/galette/galette/pull/81

(je n'ai absolument pas testé ! :))

#13

Updated by Alain Paris 2 months ago

Bonjour,
Je viens d'essayer avec la feature/gaptcha j'ai une erreur mais rien dans les logs:
- ERREUR -
Invalid captcha

Quand ce sera OK a voir s'il on peut avoir des nombres négatifs (8 retired to 2)

#14

Updated by Alain Paris 2 months ago

Pardon,le nom du fichier log n'est plus galette_run ....et il y a ca:

::1 - 2020-11-08 14:59:33 - DEBUG - Old Temporary passwords has been deleted.
::1 - 2020-11-08 14:59:34 - DEBUG - Old Temporary passwords has been deleted.
::1 - 2020-11-08 14:59:35 - DEBUG - [Galette\Filters\MembersList|Pagination] Getting property `orderby`
::1 - 2020-11-08 14:59:35 - DEBUG - [MembersList] Setting property `query`
::1 - 2020-11-08 14:59:35 - DEBUG - [Galette\Filters\MembersList|Pagination] Getting property `current_page`
::1 - 2020-11-08 14:59:35 - DEBUG - [Galette\Filters\MembersList|Pagination] Getting property `pages`
::1 - 2020-11-08 14:59:35 - DEBUG - [Galette\Filters\MembersList|Pagination] Getting property `current_page`

#15

Updated by Johan Cwiklinski 2 months ago

Alain Paris a écrit (#note-14):

Pardon,le nom du fichier log n'est plus galette_run ....et il y a ca:

Ha oui, je devais en parler sur la liste dév, j'ai un peu zappé ; désolé.

Pour le souci, je vais essayer de tester/régler ça au plus vite :)

#16

Updated by Johan Cwiklinski 2 months ago

  • Status changed from Nouveau to In Progress

J'ai corrigé le problème de vérification, ça fonctionne maintenant.

En revanche, j'ai lancé cette vérification en tout premier lieu - pour éviter des étapes inutiles. Le problème, c'ets que du coup les données adhérent envoyées ne sont pas traitées ; et l'on est donc redirigés sur un formulaire totalement vide en cas d'erreur... :( Il faudra que je corrige cela.

#17

Updated by Johan Cwiklinski 2 months ago

Tout devrait être OK maintenant. Les traductions ne sont pas faites (ça partira sur Weblate quand la fonctionnalité sera réintégrée) ; mais les chiffres en toutes lettres apparaîtront bien dans la locale courante.

#18

Updated by Johan Cwiklinski 2 months ago

  • Status changed from In Progress to Résolu
  • % Done changed from 0 to 100
#19

Updated by Johan Cwiklinski 2 months ago

  • Status changed from Résolu to Fermé

Also available in: Atom PDF