Questo articolo è il primo di una serie di post che sto scrivendo sulla gestione di vari prodotti e siti Web SaaS negli ultimi 8 anni. Condividerò alcuni dei problemi che ho affrontato, le lezioni che ho imparato, gli errori che ho commesso e forse alcune cose che sono andate bene. Fammi sapere cosa ne pensi!
Nel 2019 o 2020 avevo deciso di riscrivere l'intero backend di Blocca mittente, un'applicazione SaaS che aiuta gli utenti a creare migliori blocchi di posta elettronica, tra le altre funzionalità. Nel frattempo, ho aggiunto alcune nuove funzionalità e sono passato a tecnologie molto più moderne. Ho eseguito i test, distribuito il codice, testato manualmente tutto in produzione e, a parte alcune cianfrusaglie casuali, tutto sembrava funzionare alla grande. Vorrei che questa fosse la fine della storia, ma...
Alcune settimane dopo, un cliente mi ha informato (cosa di per sé imbarazzante) che il servizio non funzionava e che riceveva molte email che avrebbero dovuto essere bloccate nella sua casella di posta, quindi ho indagato. Molte volte questo problema è dovuto al fatto che Google rimuove la connessione dal nostro servizio all'account dell'utente, cosa che il sistema gestisce avvisando l'utente via email e chiedendogli di riconnettersi, ma questa volta si trattava di qualcos'altro.
Sembrava che il lavoratore di backend che gestisce il controllo delle e-mail rispetto ai blocchi degli utenti continuasse a bloccarsi ogni 5-10 minuti. La parte più strana è che non c'erano errori nei registri, la memoria andava bene, ma la CPU occasionalmente aumentava in momenti apparentemente casuali. Quindi per le successive 24 ore (con una pausa di 3 ore per dormire – scusate clienti 😬), ho dovuto riavviare manualmente il lavoratore ogni volta che si bloccava. Per qualche motivo, il servizio Elastic Beanstalk aspettava troppo a lungo per riavviarsi, motivo per cui ho dovuto farlo manualmente.
Il debug dei problemi in produzione è sempre una seccatura, soprattutto perché non sono riuscito a riprodurre il problema localmente, per non parlare di capire cosa lo stava causando. Quindi, come ogni “bravo” sviluppatore, ho appena iniziato a registrare qualunque cosa e ho aspettato che il server si bloccasse di nuovo. Dato che la CPU registrava picchi periodici, ho pensato che non si trattasse di un problema macro (come quando si esaurisce la memoria) e che probabilmente fosse causato da un'e-mail o da un utente specifico. Quindi ho provato a restringere il campo:
- Si è verificato un arresto anomalo su un determinato ID o tipo di posta elettronica?
- Si è verificato un arresto anomalo per un determinato cliente?
- Si è schiantato a intervalli regolari?
Dopo ore trascorse così, e guardando i registri più a lungo di quanto avrei voluto, alla fine, ho ristretto il campo a un cliente specifico. Da lì, lo spazio di ricerca si è ristretto un po’: molto probabilmente si trattava di una regola di blocco o di un’e-mail specifica su cui il nostro server continuava a riprovare. Fortunatamente per me, si è trattato del primo, che è un problema molto più semplice da risolvere dato che siamo un'azienda molto attenta alla privacy e non archiviamo né visualizziamo alcun dato di posta elettronica.
Prima di affrontare il problema esatto, parliamo prima di una delle funzionalità di Block Sender. All'epoca molti clienti richiedevano il blocco dei caratteri jolly, che avrebbe consentito loro di bloccare determinati tipi di indirizzi e-mail che seguivano lo stesso schema. Ad esempio, se desideri bloccare tutte le email provenienti da indirizzi email di marketing, potresti utilizzare il carattere jolly marketing@*
e bloccherebbe tutte le email provenienti da qualsiasi indirizzo iniziato con marketing@
.
Una cosa a cui non avevo pensato è che non tutti capiscono come funzionano i caratteri jolly. Supponevo che la maggior parte delle persone li avrebbe usati nello stesso modo in cui lo faccio io come sviluppatore, usandone uno *
per rappresentare un numero qualsiasi di caratteri. Sfortunatamente, questo particolare utente aveva pensato che dovessi usare un carattere jolly per ogni carattere che desideri abbinare. Nel loro caso, volevano bloccare tutte le email provenienti da un determinato dominio (che è una funzionalità nativa di Block Sender, ma non devono averlo realizzato, il che è di per sé un intero problema). Quindi invece di usare *@example.com
, loro hanno usato **********@example.com
.
POV: Osservare i tuoi utenti utilizzare la tua app…
Per gestire i caratteri jolly sul nostro server di lavoro, utilizziamo la libreria Node.js abbinatore, che aiuta con la corrispondenza globale trasformandolo in un'espressione regolare. Questa biblioteca poi trasformerebbe **********@example.com
in qualcosa di simile alla seguente regex:
/[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*@example.com/i
Se hai esperienza con le espressioni regolari, sai che possono diventare molto complicate molto rapidamente, soprattutto a livello computazionale. Far corrispondere l'espressione di cui sopra a qualsiasi lunghezza ragionevole di testo diventa molto costoso dal punto di vista computazionale, il che ha finito per impegnare la CPU sul nostro server di lavoro. Questo è il motivo per cui il server si blocca ogni pochi minuti; si bloccherebbe cercando di abbinare un'espressione regolare complessa a un indirizzo email. Pertanto, ogni volta che questo utente riceveva un'e-mail, oltre a tutti i tentativi integrati per gestire gli errori temporanei, il nostro server si bloccava.
Allora come ho risolto questo problema? Ovviamente, la soluzione rapida era trovare tutti i blocchi con più caratteri jolly in successione e correggerli. Ma dovevo anche fare un lavoro migliore per disinfettare l'input dell'utente. Qualsiasi utente può inserire una regex e disattivare l'intero sistema con a Attacco ReDoS.
Dai un'occhiata alla nostra guida pratica e pratica per l'apprendimento di Git, con le migliori pratiche, gli standard accettati dal settore e il cheat sheet incluso. Smetti di cercare su Google i comandi Git e in realtà imparare esso!
Gestire questo caso particolare è stato abbastanza semplice: rimuovi i caratteri jolly successivi:
block = block.replace(/*+/g, '*')
Ma ciò lascia comunque l’app aperta ad altri tipi di attacchi ReDoS. Fortunatamente ci sono una serie di pacchetti/librerie che ci aiutano anche con questi tipi:
Utilizzando una combinazione delle soluzioni di cui sopra e altre misure di salvaguardia, sono riuscito a evitare che ciò accada di nuovo. Ma è stato un buon promemoria del fatto che non puoi mai fidarti dell'input dell'utente e che dovresti sempre disinfettarlo prima di utilizzarlo nella tua applicazione. Non sapevo nemmeno che questo fosse un potenziale problema finché non è successo a me, quindi spero che questo aiuti qualcun altro a evitare lo stesso problema.
Hai domande, commenti o vuoi condividere una tua storia? Raggiungi Twitter!
- Distribuzione di contenuti basati su SEO e PR. Ricevi amplificazione oggi.
- PlatoData.Network Generativo verticale Ai. Potenzia te stesso. Accedi qui.
- PlatoAiStream. Intelligenza Web3. Conoscenza amplificata. Accedi qui.
- PlatoneESG. Carbonio, Tecnologia pulita, Energia, Ambiente, Solare, Gestione dei rifiuti. Accedi qui.
- Platone Salute. Intelligence sulle biotecnologie e sulle sperimentazioni cliniche. Accedi qui.
- Fonte: https://stackabuse.com/behind-the-scenes-never-trust-user-input/
- :ha
- :È
- :non
- $ SU
- 1
- 20
- 2019
- 2020
- 24
- 8
- a
- capace
- Chi siamo
- sopra
- Il mio account
- effettivamente
- aggiunto
- aggiunta
- indirizzo
- indirizzi
- ancora
- contro
- Tutti
- consentire
- da solo
- anche
- sempre
- tra
- an
- ed
- in qualsiasi
- App
- Applicazioni
- SONO
- articolo
- AS
- chiedendo
- assunto
- At
- attacchi
- evitare
- consapevole
- BACKEND
- BE
- Beanstalk
- diventa
- stato
- prima
- dietro
- dietro le quinte
- essendo
- Meglio
- Po
- Bloccare
- blocco
- Blocchi
- sistema
- Rompere
- costruito
- ma
- by
- Materiale
- Può ottenere
- che
- Custodie
- ha causato
- causando
- certo
- carattere
- caratteri
- verifica
- codice
- combinazione
- Commenti
- azienda
- complesso
- complicato
- computazionale
- veloce
- correggere
- potuto
- non poteva
- Crash
- Incidentato
- Crashing
- creare
- cliente
- Clienti
- dati
- trattati
- deciso
- schierato
- Costruttori
- DID
- didn
- do
- dominio
- don
- giù
- dovuto
- ogni
- più facile
- altro
- fine
- finito
- finisce
- entrare
- Intero
- errori
- particolarmente
- Anche
- alla fine
- Ogni
- tutti
- qualunque cosa
- esempio
- costoso
- esperienza
- espressione
- fallimenti
- abbastanza
- lontano
- caratteristica
- Caratteristiche
- pochi
- figura
- capito
- Trovare
- sottile
- Nome
- Fissare
- Focus
- seguito
- i seguenti
- Nel
- Ex
- da
- ottenere
- ottenere
- gif
- Idiota
- dato
- buono
- grande
- guida
- ha avuto
- maniglia
- Maniglie
- mani su
- successo
- Happening
- Avere
- Aiuto
- aiuta
- Fiduciosamente
- ORE
- librarsi
- Come
- HTTPS
- i
- ID
- if
- in
- incluso
- ingresso
- invece
- ai miglioramenti
- problema
- sicurezza
- IT
- stessa
- Lavoro
- ad appena
- tenere
- Sapere
- Cognome
- dopo
- imparato
- apprendimento
- Lunghezza
- Lezioni
- lasciare
- Livello
- LG
- Biblioteca
- piace
- probabile
- ll
- a livello locale
- registrazione
- Lunghi
- più a lungo
- guardò
- lotti
- Macro
- fatto
- manualmente
- molti
- Marketing
- partita
- corrispondenza
- può essere
- me
- Memorie
- Minuti
- errori
- moderno
- tecnologie moderne
- Scopri di più
- maggior parte
- molti
- multiplo
- devono obbligatoriamente:
- stretto
- nativo
- di applicazione
- mai
- New
- Nuove funzionalità
- GENERAZIONE
- no
- nodo
- Node.js
- notificando
- numero
- Probabilità
- of
- on
- ONE
- aprire
- or
- Altro
- nostro
- su
- proprio
- Dolore
- parte
- particolare
- Cartamodello
- Persone
- Platone
- Platone Data Intelligence
- PlatoneDati
- Post
- potenziale
- Pratico
- prevenire
- probabilmente
- Problema
- processi
- Produzione
- Prodotti
- Domande
- Presto
- rapidamente
- abbastanza
- casuale
- RE
- raggiungere
- realizzato
- ragione
- ragionevole
- ricevuto
- ricollegare
- regex
- Basic
- promemoria
- rimuovere
- rimozione
- rappresentare
- destra
- Anello
- Regola
- Correre
- running
- s
- SaaS
- garanzie
- stesso
- Scene
- Cerca
- sembrava
- apparentemente
- trasmettitore
- Serie
- server
- servizio
- Shadow
- Condividi
- compartecipazione
- foglio
- dovrebbero
- Un'espansione
- da
- sonno
- So
- Soluzioni
- alcuni
- Qualcuno
- qualcosa
- lo spazio
- specifico
- spuntone
- Impilamento
- standard
- iniziato
- Ancora
- Fermare
- Tornare al suo account
- Storia
- sistema
- Fai
- Parlare
- Tecnologie
- temporaneo
- testato
- test
- testo
- di
- che
- I
- loro
- Li
- poi
- Là.
- Strumenti Bowman per analizzare le seguenti finiture:
- di
- cosa
- cose
- think
- questo
- tempo
- volte
- a
- pure
- transizione
- provato
- Affidati ad
- cerca
- TURNO
- Svolta
- Digitare
- Tipi di
- capisce
- purtroppo
- fino a quando
- aggiornato
- us
- uso
- utilizzato
- Utente
- utenti
- utilizzando
- vario
- Ve
- molto
- via
- Visualizza
- In attesa
- volere
- ricercato
- Prima
- non lo era
- guardare
- Modo..
- we
- siti web
- Settimane
- WELL
- è andato
- sono stati
- Che
- quando
- quale
- tutto
- perché
- wikipedia
- desiderio
- con
- Lavora
- lavoratore
- lavoro
- sarebbe
- scrittura
- anni
- Tu
- Trasferimento da aeroporto a Sharm
- zefiro