Cet article est le premier d'une série d'articles que j'écris sur l'exécution de divers produits et sites Web SaaS au cours des 8 dernières années. Je partagerai certains des problèmes que j'ai résolus, les leçons que j'ai apprises, les erreurs que j'ai commises et peut-être quelques éléments qui se sont bien passés. Faites le moi savoir ce que tu penses!
En 2019 ou 2020, j'avais décidé de réécrire tout le backend pour Bloquer l'expéditeur, une application SaaS qui aide les utilisateurs à créer de meilleurs blocs de courrier électronique, entre autres fonctionnalités. Au cours du processus, j'ai ajouté quelques nouvelles fonctionnalités et mis à niveau vers des technologies beaucoup plus modernes. J'ai exécuté les tests, déployé le code, tout testé manuellement en production et, à part quelques bricoles aléatoires, tout semblait bien fonctionner. J'aurais aimé que ce soit la fin de l'histoire, mais…
Quelques semaines plus tard, un client m'a informé (ce qui est embarrassant en soi) que le service ne fonctionnait pas et qu'il recevait de nombreux e-mails qui devraient être bloqués dans sa boîte de réception. J'ai donc enquêté. Plusieurs fois, ce problème est dû au fait que Google supprime la connexion de notre service au compte de l'utilisateur, ce que le système gère en avertissant l'utilisateur par e-mail et en lui demandant de se reconnecter, mais cette fois, c'était autre chose.
Il semblait que le travailleur back-end qui gère la vérification des e-mails par rapport aux blocages des utilisateurs continuait de planter toutes les 5 à 10 minutes. Le plus étrange : il n'y avait aucune erreur dans les journaux, la mémoire était bonne, mais le processeur augmentait occasionnellement à des moments apparemment aléatoires. Ainsi, pendant les 24 heures suivantes (avec une pause de 3 heures pour dormir – désolé clients 😬), j'ai dû redémarrer manuellement le travailleur à chaque fois qu'il plantait. Pour une raison quelconque, le service Elastic Beanstalk attendait beaucoup trop longtemps pour redémarrer, c'est pourquoi j'ai dû le faire manuellement.
Le débogage des problèmes en production est toujours pénible, d'autant plus que je n'ai pas pu reproduire le problème localement, et encore moins en comprendre la cause. Donc comme tout « bon » développeur, je viens de commencer à me connecter peut et j'ai attendu que le serveur plante à nouveau. Étant donné que le processeur augmentait périodiquement, j'ai pensé que ce n'était pas un problème de macro (comme lorsque vous manquez de mémoire) et qu'il était probablement dû à un e-mail ou à un utilisateur spécifique. J'ai donc essayé de le préciser :
- Est-ce qu'il s'est écrasé sur un certain identifiant ou type de courrier électronique ?
- Est-ce que cela a planté pour un client donné ?
- Est-ce qu'il s'est écrasé à intervalles réguliers ?
Après des heures de travail et en regardant les journaux plus longtemps que je ne le souhaiterais, j'ai finalement réussi à le limiter à un client spécifique. À partir de là, l’espace de recherche s’est considérablement rétréci – il s’agissait très probablement d’une règle de blocage ou d’un e-mail spécifique sur lequel notre serveur réessayait sans cesse. Heureusement pour moi, il s'agissait du premier problème, ce qui est un problème beaucoup plus facile à déboguer étant donné que nous sommes une entreprise très axée sur la confidentialité et que nous ne stockons ni ne consultons aucune donnée de courrier électronique.
Avant d'entrer dans le vif du sujet, parlons d'abord de l'une des fonctionnalités de Block Sender. À l’époque, de nombreux clients demandaient un blocage par caractère générique, ce qui leur permettrait de bloquer certains types d’adresses e-mail suivant le même modèle. Par exemple, si vous souhaitez bloquer tous les e-mails provenant d'adresses e-mail marketing, vous pouvez utiliser le caractère générique marketing@*
et cela bloquerait tous les e-mails provenant de n'importe quelle adresse commençant par marketing@
.
Une chose à laquelle je n'ai pas pensé est que tout le monde ne comprend pas comment fonctionnent les caractères génériques. J'ai supposé que la plupart des gens les utiliseraient de la même manière que moi en tant que développeur, en utilisant un *
pour représenter n'importe quel nombre de caractères. Malheureusement, cet utilisateur avait supposé que vous deviez utiliser un caractère générique pour chaque caractère que vous vouliez faire correspondre. Dans leur cas, ils voulaient bloquer tous les e-mails d'un certain domaine (ce qui est une fonctionnalité native de Block Sender, mais ils ne doivent pas s'en rendre compte, ce qui est tout un problème en soi). Donc au lieu d'utiliser *@example.com
, Ils ont utilisé **********@example.com
.
POV : Regarder vos utilisateurs utiliser votre application…
Pour gérer les caractères génériques sur notre serveur de travail, nous utilisons la bibliothèque Node.js matcheur, qui facilite la correspondance globale en le transformant en expression régulière. Cette bibliothèque deviendrait alors **********@example.com
en quelque chose comme l'expression régulière suivante :
/[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*@example.com/i
Si vous avez de l'expérience avec les regex, vous savez qu'elles peuvent devenir très compliquées très rapidement, notamment au niveau informatique. Faire correspondre l'expression ci-dessus à une longueur raisonnable de texte devient très coûteux en termes de calcul, ce qui finit par immobiliser le processeur de notre serveur de travail. C'est pourquoi le serveur plantait toutes les quelques minutes ; il resterait bloqué en essayant de faire correspondre une expression régulière complexe à une adresse e-mail. Ainsi, chaque fois que cet utilisateur recevait un e-mail, en plus de toutes les tentatives que nous avions intégrées pour gérer les échecs temporaires, cela faisait planter notre serveur.
Alors, comment ai-je résolu ce problème ? Évidemment, la solution rapide consistait à rechercher successivement tous les blocs comportant plusieurs caractères génériques et à les corriger. Mais je devais également faire un meilleur travail de nettoyage des entrées des utilisateurs. N'importe quel utilisateur peut saisir une expression régulière et arrêter l'ensemble du système avec un Attaque ReDoS.
Consultez notre guide pratique et pratique pour apprendre Git, avec les meilleures pratiques, les normes acceptées par l'industrie et la feuille de triche incluse. Arrêtez de googler les commandes Git et en fait apprendre il!
La gestion de ce cas particulier était assez simple : supprimez les caractères génériques successifs :
block = block.replace(/*+/g, '*')
Mais cela laisse toujours l’application ouverte à d’autres types d’attaques ReDoS. Heureusement, il existe également un certain nombre de packages/bibliothèques pour nous aider avec ces types :
En utilisant une combinaison des solutions ci-dessus et d'autres mesures de protection, j'ai pu empêcher que cela ne se reproduise. Mais c'était un bon rappel que vous ne pouvez jamais faire confiance aux entrées de l'utilisateur et que vous devez toujours les nettoyer avant de les utiliser dans votre application. Je ne savais même pas qu'il s'agissait d'un problème potentiel jusqu'à ce que cela m'arrive, alors j'espère que cela aidera quelqu'un d'autre à éviter le même problème.
Vous avez des questions, des commentaires ou souhaitez partager votre propre histoire ? Contactez-nous Twitter!
- Contenu propulsé par le référencement et distribution de relations publiques. Soyez amplifié aujourd'hui.
- PlatoData.Network Ai générative verticale. Autonomisez-vous. Accéder ici.
- PlatoAiStream. Intelligence Web3. Connaissance Amplifiée. Accéder ici.
- PlatonESG. Carbone, Technologie propre, Énergie, Environnement, Solaire, La gestion des déchets. Accéder ici.
- PlatoHealth. Veille biotechnologique et essais cliniques. Accéder ici.
- La source: https://stackabuse.com/behind-the-scenes-never-trust-user-input/
- :possède
- :est
- :ne pas
- $UP
- 1
- 20
- 2019
- 2020
- 24
- 8
- a
- Capable
- Qui sommes-nous
- au dessus de
- Compte
- actually
- ajoutée
- ajout
- propos
- adresses
- encore
- à opposer à
- Tous
- permettre
- seul
- aussi
- toujours
- parmi
- an
- ainsi que les
- tous
- appli
- Application
- SONT
- article
- AS
- demandant
- assumé
- At
- Attaques
- éviter
- conscients
- backend
- BE
- tige d'haricot
- devient
- était
- before
- derrière
- Dans les coulisses
- va
- Améliorée
- Bit
- Block
- blocage
- Blocs
- frontière
- Pause
- construit
- mais
- by
- CAN
- Peut obtenir
- les soins
- maisons
- causé
- causer
- certaines
- caractère
- caractères
- vérification
- code
- combinaison
- commentaires
- Société
- complexe
- compliqué
- calcul
- connexion
- correct
- pourriez
- ne pouvait pas
- Crash
- Écrasé
- S'écraser
- engendrent
- des clients
- Clients
- données
- traité
- décidé
- déployé
- Développeur
- DID
- didn
- do
- domaine
- Don
- down
- deux
- chacun
- plus facilement
- d'autre
- emails
- fin
- terminé
- se termine
- Entrer
- Tout
- Erreurs
- notamment
- Pourtant, la
- faire une éventuelle
- Chaque
- tout le monde
- peut
- exemple
- cher
- d'experience
- expression
- échecs
- équitablement
- loin
- Fonctionnalité
- Fonctionnalités:
- few
- Figure
- figuré
- Trouvez
- fin
- Prénom
- Fixer
- Focus
- suivi
- Abonnement
- Pour
- Ancien
- de
- obtenez
- obtention
- gif
- Git
- donné
- Bien
- l'
- guide
- ait eu
- manipuler
- Poignées
- hands-on
- arrivé
- EN COURS
- Vous avez
- vous aider
- aide
- Avec optimisme
- HEURES
- flotter
- Comment
- HTTPS
- i
- ID
- if
- in
- inclus
- contribution
- plutôt ;
- développement
- aide
- vous aider à faire face aux problèmes qui vous perturbent
- IT
- lui-même
- Emploi
- juste
- conservé
- Savoir
- Nom de famille
- plus tard
- savant
- apprentissage
- Longueur
- Cours
- laisser
- Niveau
- LG
- Bibliothèque
- comme
- Probable
- ll
- localement
- enregistrement
- Location
- plus long
- regardé
- beaucoup
- Macro
- LES PLANTES
- manuellement
- de nombreuses
- Stratégie
- Match
- assorti
- peut être
- me
- Mémoire
- Minutes
- erreurs
- Villas Modernes
- technologies modernes
- PLUS
- (en fait, presque toutes)
- beaucoup
- plusieurs
- must
- étroit
- indigène
- nécessaire
- n'allons jamais
- Nouveauté
- Nouvelles fonctionnalités
- next
- aucune
- nœud
- Node.js
- notification
- nombre
- Chances
- of
- on
- ONE
- ouvert
- or
- Autre
- nos
- ande
- propre
- Pain
- partie
- particulier
- Patron de Couture
- Personnes
- Platon
- Intelligence des données Platon
- PlatonDonnées
- Poteaux
- défaillances
- Méthode
- empêcher
- Probablement
- Problème
- processus
- Vidéo
- Produits
- fréquemment posées
- Rapide
- vite.
- assez
- aléatoire
- RE
- nous joindre
- réalisé
- raison
- raisonnable
- reçu
- reconnecter
- regex
- Standard
- rappel
- supprimez
- enlever
- représentent
- bon
- Bagues
- Règle
- Courir
- pour le running
- s
- SaaS.
- garanties
- même
- Scènes
- Rechercher
- semblait
- apparemment
- expéditeur
- Série
- serveur
- service
- Shadow
- Partager
- partage
- feuille
- devrait
- étapes
- depuis
- sleep
- So
- Solutions
- quelques
- Quelqu'un
- quelque chose
- Space
- groupe de neurones
- épi
- Stackabuse
- Normes
- j'ai commencé
- Encore
- Arrêter
- Boutique
- Histoire
- combustion propre
- Prenez
- discutons-en
- Les technologies
- temporaire
- examiné
- tests
- texte
- que
- qui
- Les
- leur
- Les
- puis
- Là.
- Ces
- l'ont
- chose
- des choses
- penser
- this
- fiable
- fois
- à
- trop
- transition
- essayé
- La confiance
- essayer
- TOUR
- Tournant
- type
- types
- comprend
- malheureusement
- jusqu'à
- mis à jour
- us
- utilisé
- d'utiliser
- Utilisateur
- utilisateurs
- en utilisant
- divers
- Ve
- très
- via
- Voir
- Attendre
- souhaitez
- voulu
- était
- était
- personne(s) regarde(nt) cette fiche produit
- Façon..
- we
- sites Internet
- Semaines
- WELL
- est allé
- ont été
- Quoi
- quand
- qui
- la totalité
- why
- Wikipédia
- souhaiter
- comprenant
- activités principales
- travailleur
- de travail
- pourra
- écriture
- années
- Vous n'avez
- Votre
- zéphyrnet