Dieser Artikel ist der erste einer Reihe von Beiträgen, die ich über den Betrieb verschiedener SaaS-Produkte und Websites in den letzten 8 Jahren schreibe. Ich werde einige der Probleme mitteilen, mit denen ich mich befasst habe, Lektionen, die ich gelernt habe, Fehler, die ich gemacht habe, und vielleicht ein paar Dinge, die richtig gelaufen sind. Gib mir Bescheid was Sie denken!
Bereits 2019 oder 2020 hatte ich beschlossen, das gesamte Backend für neu zu schreiben Absender blockieren, eine SaaS-Anwendung, die Benutzern unter anderem dabei hilft, bessere E-Mail-Blockierungen zu erstellen. Dabei habe ich einige neue Funktionen hinzugefügt und auf deutlich modernere Technologien umgestellt. Ich habe die Tests durchgeführt, den Code bereitgestellt, alles in der Produktion manuell getestet und bis auf ein paar zufällige Kleinigkeiten schien alles großartig zu funktionieren. Ich wünschte, das wäre das Ende der Geschichte, aber ...
Ein paar Wochen später wurde ich von einem Kunden benachrichtigt (was an sich schon peinlich ist), dass der Dienst nicht funktionierte und er viele E-Mails in seinem Posteingang erhielt, die blockiert werden sollten, also habe ich der Sache nachgegangen. Oft ist dieses Problem darauf zurückzuführen, dass Google die Verbindung von unserem Dienst zum Konto des Nutzers entfernt hat. Das System kümmert sich darum, indem es den Nutzer per E-Mail benachrichtigt und ihn auffordert, die Verbindung wiederherzustellen. Diesmal war es jedoch etwas anderes.
Es sah so aus, als ob der Backend-Worker, der E-Mails anhand von Benutzersperren überprüft, alle 5–10 Minuten abstürzte. Das Seltsamste daran: Es gab keine Fehler in den Protokollen, der Speicher war in Ordnung, aber die CPU sprang gelegentlich zu scheinbar zufälligen Zeiten an. Für die nächsten 24 Stunden (mit einer 3-stündigen Schlafpause – tut mir leid, Kunden 😬) musste ich den Worker bei jedem Absturz manuell neu starten. Aus irgendeinem Grund wartete der Elastic Beanstalk-Dienst viel zu lange auf den Neustart, weshalb ich ihn manuell durchführen musste.
Das Debuggen von Problemen in der Produktion ist immer mühsam, vor allem, weil ich das Problem nicht lokal reproduzieren konnte, geschweige denn herausfinden konnte, was es verursachte. Wie jeder „gute“ Entwickler habe ich also gerade mit der Protokollierung begonnen alles und wartete darauf, dass der Server erneut abstürzte. Da die CPU in regelmäßigen Abständen Spitzenwerte aufwies, ging ich davon aus, dass es sich nicht um ein Makroproblem handelte (z. B. wenn Ihnen der Arbeitsspeicher ausgeht) und dass es wahrscheinlich durch eine bestimmte E-Mail oder einen bestimmten Benutzer verursacht wurde. Also habe ich versucht, es einzugrenzen:
- Ist es bei einer bestimmten E-Mail-ID oder einem bestimmten E-Mail-Typ abgestürzt?
- Stürzte es bei einem bestimmten Kunden ab?
- Stürzte es in regelmäßigen Abständen ab?
Nachdem ich stundenlang damit beschäftigt war und länger auf Protokolle starrte, als mir lieb war, konnte ich es schließlich auf einen bestimmten Kunden eingrenzen. Von da an wurde der Suchraum erheblich enger – es handelte sich höchstwahrscheinlich um eine Blockierungsregel oder eine bestimmte E-Mail, die unser Server immer wieder versuchte. Zum Glück war es ersteres, was viel einfacher zu beheben ist, wenn man bedenkt, dass wir ein sehr datenschutzorientiertes Unternehmen sind und keine E-Mail-Daten speichern oder einsehen.
Bevor wir auf das genaue Problem eingehen, sprechen wir zunächst über eine der Funktionen von Block Sender. Zu dieser Zeit fragten viele Kunden nach einer Wildcard-Blockierung, die es ihnen ermöglichen würde, bestimmte Arten von E-Mail-Adressen zu blockieren, die demselben Muster folgten. Wenn Sie beispielsweise alle E-Mails von Marketing-E-Mail-Adressen blockieren möchten, können Sie den Platzhalter verwenden marketing@*
und es würde alle E-Mails von jeder Adresse blockieren, die mit begann marketing@
.
Eine Sache, über die ich nicht nachgedacht habe, ist, dass nicht jeder versteht, wie Wildcards funktionieren. Ich ging davon aus, dass die meisten Leute sie auf die gleiche Weise verwenden würden wie ich als Entwickler, indem ich eines verwende *
um eine beliebige Anzahl von Zeichen darzustellen. Leider hatte dieser bestimmte Benutzer angenommen, dass Sie es verwenden müssten ein Platzhalter für jedes Zeichen, das Sie abgleichen möchten. In ihrem Fall wollten sie alle E-Mails von einer bestimmten Domain blockieren (was eine native Funktion von Block Sender ist, aber sie dürften es nicht bemerkt haben, was an sich schon ein ganzes Problem darstellt). Also statt zu verwenden *@example.com
, Sie benutzten **********@example.com
.
POV: Beobachten Sie, wie Ihre Benutzer Ihre App nutzen …
Um Platzhalter auf unserem Arbeitsserver zu verarbeiten, verwenden wir die Node.js-Bibliothek Matcher, was beim Glob-Matching hilft, indem es in einen regulären Ausdruck umgewandelt wird. Diese Bibliothek würde sich dann umdrehen **********@example.com
in so etwas wie den folgenden regulären Ausdruck:
/[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*@example.com/i
Wenn Sie Erfahrung mit Regex haben, wissen Sie, dass diese sehr schnell sehr kompliziert werden können, insbesondere auf rechnerischer Ebene. Das Anpassen des obigen Ausdrucks an eine beliebige Textlänge in angemessener Länge wird sehr rechenintensiv, was letztendlich dazu führt, dass die CPU auf unserem Arbeitsserver blockiert wird. Aus diesem Grund stürzte der Server alle paar Minuten ab; Es würde stecken bleiben, wenn versucht würde, einen komplexen regulären Ausdruck einer E-Mail-Adresse zuzuordnen. Jedes Mal, wenn dieser Benutzer eine E-Mail erhielt, kam es zusätzlich zu allen Wiederholungsversuchen, die wir zur Behandlung vorübergehender Fehler eingebaut hatten, zu einem Absturz unseres Servers.
Wie habe ich das behoben? Die schnelle Lösung bestand offensichtlich darin, alle Blöcke mit mehreren Platzhaltern nacheinander zu finden und zu korrigieren. Aber ich musste auch die Benutzereingaben besser bereinigen. Jeder Benutzer könnte einen regulären Ausdruck eingeben und mit einem das gesamte System lahmlegen ReDoS-Angriff.
Sehen Sie sich unseren praxisnahen, praktischen Leitfaden zum Erlernen von Git an, mit Best Practices, branchenweit akzeptierten Standards und einem mitgelieferten Spickzettel. Hören Sie auf, Git-Befehle zu googeln und tatsächlich in Verbindung, um es!
Die Handhabung dieses speziellen Falles war recht einfach: Entfernen Sie aufeinanderfolgende Platzhalterzeichen:
block = block.replace(/*+/g, '*')
Dadurch ist die App jedoch immer noch anfällig für andere Arten von ReDoS-Angriffen. Glücklicherweise gibt es eine Reihe von Paketen/Bibliotheken, die uns auch bei diesen Typen helfen:
Durch eine Kombination der oben genannten Lösungen und anderer Sicherheitsmaßnahmen konnte ich verhindern, dass so etwas noch einmal passiert. Aber es war eine gute Erinnerung daran, dass Sie Benutzereingaben niemals vertrauen können und diese immer bereinigen sollten, bevor Sie sie in Ihrer Anwendung verwenden. Ich war mir nicht einmal bewusst, dass dies ein potenzielles Problem sein könnte, bis es mir selbst passierte, also hoffe ich, dass dies jemand anderem hilft, das gleiche Problem zu vermeiden.
Haben Sie Fragen, Kommentare oder möchten Sie eine eigene Geschichte erzählen? Kontaktieren Sie uns Twitter!
- SEO-gestützte Content- und PR-Distribution. Holen Sie sich noch heute Verstärkung.
- PlatoData.Network Vertikale generative KI. Motiviere dich selbst. Hier zugreifen.
- PlatoAiStream. Web3-Intelligenz. Wissen verstärkt. Hier zugreifen.
- PlatoESG. Kohlenstoff, CleanTech, Energie, Umwelt, Solar, Abfallwirtschaft. Hier zugreifen.
- PlatoHealth. Informationen zu Biotechnologie und klinischen Studien. Hier zugreifen.
- Quelle: https://stackabuse.com/behind-the-scenes-never-trust-user-input/
- :hast
- :Ist
- :nicht
- $UP
- 1
- 20
- 2019
- 2020
- 24
- 8
- a
- Fähig
- Über uns
- oben
- Konto
- berührt das Schneidwerkzeug
- hinzugefügt
- Zusatz
- Adresse
- Adressen
- aufs Neue
- gegen
- Alle
- erlauben
- allein
- ebenfalls
- immer
- unter
- an
- machen
- jedem
- App
- Anwendung
- SIND
- Artikel
- AS
- fragen
- angenommen
- At
- Anschläge
- vermeiden
- bewusst
- Backend
- BE
- Beanstalk
- wird
- war
- Bevor
- hinter
- hinter den Kulissen
- Sein
- Besser
- Bit
- Blockieren
- Sperrung
- Blockiert
- Grenze
- Break
- erbaut
- aber
- by
- CAN
- Kann bekommen
- österreichische Unternehmen
- Häuser
- verursacht
- verursacht
- sicher
- Charakter
- Zeichen
- Überprüfung
- Code
- Kombination
- Bemerkungen
- Unternehmen
- Komplex
- kompliziert
- rechnerisch
- Verbindung
- und beseitigen Muskelschwäche
- könnte
- könnte nicht
- Crash
- Abgestürzt
- Crashing
- erstellen
- Kunde
- Kunden
- technische Daten
- behandelt
- entschieden
- Einsatz
- Entwickler:in / Unternehmen
- DID
- didn
- do
- Domain
- Don
- nach unten
- zwei
- jeder
- einfacher
- sonst
- E-Mails
- Ende
- beendet
- endet
- Enter
- Ganz
- Fehler
- insbesondere
- Sogar
- schließlich
- Jedes
- jedermann
- alles
- Beispiel
- teuer
- ERFAHRUNGEN
- Ausdruck
- Ausfälle
- ziemlich
- weit
- Merkmal
- Eigenschaften
- wenige
- Abbildung
- gemustert
- Finden Sie
- Ende
- Vorname
- Fixieren
- Setzen Sie mit Achtsamkeit
- gefolgt
- Folgende
- Aussichten für
- Früher
- für
- bekommen
- bekommen
- gif
- Git
- gegeben
- gut
- groß
- Guide
- hätten
- Griff
- Griffe
- praktische
- passiert
- Los
- Haben
- Hilfe
- hilft
- Hoffentlich
- STUNDEN
- schweben
- Ultraschall
- HTTPS
- i
- ID
- if
- in
- inklusive
- Varianten des Eingangssignals:
- beantragen müssen
- in
- Problem
- Probleme
- IT
- selbst
- Job
- nur
- gehalten
- Wissen
- Nachname
- später
- gelernt
- lernen
- Länge
- Programm
- lassen
- Niveau
- LG
- Bibliothek
- Gefällt mir
- wahrscheinlich
- ll
- örtlich
- Protokollierung
- Lang
- länger
- sah
- viel
- Makro
- gemacht
- manuell
- viele
- Marketing
- Spiel
- Abstimmung
- vielleicht
- me
- Memory
- Minuten
- Fehler
- modern
- moderne Technologien
- mehr
- vor allem warme
- viel
- mehrere
- sollen
- schmal
- nativen
- erforderlich
- hört niemals
- Neu
- Neue Funktionen
- weiter
- nicht
- Knoten
- Node.js
- Benachrichtigung
- Anzahl
- Odds
- of
- on
- EINEM
- XNUMXh geöffnet
- or
- Andere
- UNSERE
- besitzen
- Schmerzen
- Teil
- besondere
- Schnittmuster
- Personen
- Plato
- Datenintelligenz von Plato
- PlatoData
- BLOG-POSTS
- Potenzial
- Praktisch
- verhindern
- wahrscheinlich
- Aufgabenstellung:
- Prozessdefinierung
- Produktion
- Produkte
- Fragen
- Direkt
- schnell
- ganz
- zufällig
- RE
- erreichen
- realisiert
- Grund
- vernünftig
- Received
- schließen
- Regex
- regulär
- Erinnerung
- entfernen
- Entfernen
- vertreten
- Recht
- Ring
- Regel
- Führen Sie
- Laufen
- s
- SaaS
- Schutzmaßnahmen
- gleich
- Szenen
- Suche
- schien
- scheinbar
- Absender
- Modellreihe
- Server
- Shadow
- Teilen
- ,,teilen"
- Blatt
- sollte
- Einfacher
- da
- schlafen
- So
- Lösungen
- einige
- Jemand,
- etwas
- Raumfahrt
- spezifisch
- Spitze
- Stapelmissbrauch
- Normen
- begonnen
- Immer noch
- Stoppen
- speichern
- Geschichte
- System
- Nehmen
- Reden
- Technologies
- vorübergehend
- getestet
- Tests
- Text
- als
- zur Verbesserung der Gesundheitsgerechtigkeit
- Das
- ihr
- Sie
- dann
- Dort.
- Diese
- vom Nutzer definierten
- Ding
- think
- fehlen uns die Worte.
- Zeit
- mal
- zu
- auch
- Übergang
- versucht
- Vertrauen
- Versuch
- WENDE
- Drehung
- tippe
- Typen
- versteht
- Unglücklicherweise
- bis
- Upgrade
- us
- -
- benutzt
- Mitglied
- Nutzer
- Verwendung von
- verschiedene
- Ve
- sehr
- Anzeigen
- Warten
- wollen
- wollte
- wurde
- war
- beobachten
- Weg..
- we
- Webseiten
- Wochen
- GUT
- ging
- waren
- Was
- wann
- welche
- ganze
- warum
- Wikipedia
- wünschen
- mit
- Arbeiten
- Arbeiter
- arbeiten,
- würde
- Schreiben
- Jahr
- Du
- Ihr
- Zephyrnet