Domanda:
È sicuro consentire a un utente di digitare una regex come input di ricerca?
Xavier59
2018-08-06 05:04:00 UTC
view on stackexchange narkive permalink

Ero in un centro commerciale qualche giorno fa e ho cercato un negozio su un pannello di indicazione.

Per curiosità ho provato una ricerca con (. +) ed è stato un po 'sorpreso di avere l'elenco di tutti i negozi del centro commerciale.

Ho letto un po' di espressioni regolari malvagie ma sembra che questo tipo di attacco possa accade quando l'aggressore ha sia il controllo della voce da cercare che l'input di ricerca (la regex).

Possiamo considerare il pannello di indicazione del centro commerciale sicuro dal DOS considerando che l'attaccante ha solo il controllo dell'input di ricerca? (Lasciando da parte la possibilità che un negozio possa essere chiamato con un nome strano come aaaaaaaaaaaa.)

Se l'utente può inserire una regex e c'è un linguaggio interpretato in uso, non sarei preoccupato per il DOS;Sarei preoccupato per l'iniezione di codice.
@gowenfawr Potresti elaborare la tua risposta?Non ho trovato nulla che spieghi / spieghi questo attacco.Inoltre, ho trovato [questa domanda] (https://stackoverflow.com/questions/4579497/is-there-any-way-to-put-malicious-code-into-a-regular-expression) su SO (Iinizialmente non l'ho visto prima del mio post) ma non va in profondità nell'iniezione di codice (menziona a malapena il rischio nella sezione sandbox della risposta).
Non mi aspetterei che una mappa del centro commerciale fosse progettata per utenti sofisticati che potrebbero utilizzare espressioni regolari.Pertanto, se le espressioni regolari funzionano, suggerisce che l'applicazione stia passando ciecamente la stringa di input. Di solito è un posto dove provare varie forme di codice e SQL injection.È quella vocina che dice "Scommetto che non l'hanno fatto per progettazione ..." che fa rizzare l'antenna.Questo è un commento, non una risposta, perché (per me) non ci sono abbastanza informazioni qui per dire qualcosa di più accurato di quello.
potrebbe essere tutto lato client, nel qual caso non ci sono rischi reali.
@gowenfawr Potresti avere ragione sul fatto che un'applicazione che accetta regex in luoghi in cui non ti aspetteresti che funzionino potrebbe segnalare che ci sono problemi di sicurezza altrove, ma non credo che questo sia davvero un argomento contro l'accettazione di regex utente.Evitare qualcosa perché può stuzzicare l'interesse di un attaccante è una logica simile alla sicurezza attraverso l'oscurità: cercare di evitare l'attenzione degli aggressori è una difesa scarsa (anche più dell'oscurità) e sperare di usarla per dissuadere un attaccante dallo scoprire problemi più profondi sembrauna strategia discutibile.
Nonostante i problemi di sicurezza, mi piacerebbe eseguire il filtraggio RegEx nei pannelli di indicazione di enormi centri commerciali!
Hai testato una regex che dovrebbe ottenere corrispondenze per determinare che effettivamente utilizza regex?Se dovessi progettare una ricerca per un centro commerciale, elencerei tutti i negozi se il risultato della ricerca fosse vuoto.O l'utente sta cercando di divertirsi (come te) e il risultato non sarebbe importante o l'utente non è bravo a utilizzare la funzionalità di ricerca e dovrebbe vedere qualcosa che potrebbe essere utile per lui.
È anche possibile che il campo di ricerca ignori qualsiasi punteggiatura ed è programmato per restituire tutti i negozi per una query essenzialmente vuota.
Con alcuni motori, non c'è bisogno di fantasiose espressioni regolari.Ad esempio, con GNU `grep` 3.1 qui,` grep -E 'a {0,32767}' `consuma oltre 4 GB di RAM e il 100% di CPU a tempo indefinito, indipendentemente dall'input.
È molto facile creare una regex che si blocca anche con un input molto breve.Ad esempio, `/ ^ (((([az] * [az] *) * ([az] * [az] *) * ([az] * [az] *) * ([az] * [az]*) *) *) *) + h $ /. test ("kjhsdf") `è sufficiente per bloccare Chrome.Per motori più avanzati che eseguono tutti i tipi di analisi, potrebbe essere più difficile ma comunque possibile creare un'espressione regolare inefficiente.
@jpa Sì, ho pensato la stessa cosa, ma ho fatto altri test con altre espressioni regolari e non è il design predefinito, in realtà esegue la regex.
@nhahtdh Dipende dall'implementazione.Le espressioni regolari possono essere eseguite in tempo lineare con un buon algoritmo.https://swtch.com/~rsc/regexp/regexp1.html
@gowenfawr [Oh sì, il piccolo Bobby Tables, lo chiamiamo.] (Https://xkcd.com/327/)
@Solomonoff'sSecret: Ebbene, la maggior parte delle implementazioni utilizzate sui server web non sono lineari.
@nhahtdh Se questa è una caratteristica importante, lo sviluppatore può implementare un algoritmo lineare o utilizzare una libreria con uno.
Qualunque cosa tu faccia, non ** ** `eval ()` l'input dell'utente (o qualunque equivalente abbia la tua lingua scelta)
Sei sicuro che stia effettivamente eseguendo la regex?Potrebbe semplicemente essere che la ricerca ignori tutti i caratteri speciali per semplificare la ricerca.Ad esempio, il nome di un negozio "Spencer" potrebbe anche accettare "Spencer".
Sei risposte:
Ryan Jenkins
2018-08-06 05:38:09 UTC
view on stackexchange narkive permalink

Confronterei l'accettazione di espressioni regolari fornite dall'utente con l'analisi della maggior parte dei tipi di input utente strutturato, come stringhe di data o markdown, in termini di rischio di esecuzione del codice. Le espressioni regolari sono molto più complesse delle stringhe di data o del markdown (sebbene produrre in modo sicuro html da un markdown non attendibile abbia i suoi rischi) e quindi rappresenta più spazio per lo sfruttamento, ma il principio di base è lo stesso: lo sfruttamento implica la ricerca di effetti collaterali inaspettati dell'analisi / processo di compilazione / corrispondenza.

La maggior parte delle librerie di espressioni regolari sono mature e fanno parte della libreria standard in molte lingue, il che è un indicatore abbastanza buono (ma non certo) che è privo di problemi importanti che portano all'esecuzione del codice.
Questo è per dire, aumenta la superficie di attacco, ma non è irragionevole prendere la decisione misurata di accettare quel rischio relativamente minore.

Gli attacchi Denial of Service sono un po 'più complicati. Penso che la maggior parte delle librerie di espressioni regolari siano progettate pensando alle prestazioni, ma non considerano la mitigazione dell'input intenzionalmente lento tra i loro obiettivi di progettazione principali. L'opportunità di accettare espressioni regolari fornite dall'utente dal punto di vista DoS dipende maggiormente dalla libreria.
Ad esempio, la libreria regex .NET accetta un timeout che potrebbe essere utilizzato per mitigare gli attacchi DoS.
RE2 garantisce l'esecuzione in un tempo lineare rispetto alla dimensione dell'input che può essere accettabile se sai che il tuo corpus di ricerca rientra in un limite di dimensione ragionevole.

In situazioni in cui la disponibilità è assolutamente critica o stai cercando di ridurre al minimo la superficie di attacco il più possibile, ha senso evitare di accettare espressioni regolari dell'utente, ma penso che sia una pratica difendibile.

Sì, un timeout è la prima cosa che viene in mente per mitigare un DoS.Anche ignorando il supporto delle librerie, è abbastanza banale nella maggior parte dei linguaggi / framework per spostare la ricerca su un thread in background e avere un timeout per quel thread.
@Bob è banale sì, ma non lo è interrompere l'attività in background.Ad esempio, in un linguaggio come Java non c'è modo di terminare forzatamente un thread, quindi anche se il tuo timeout fosse scaduto non saresti in grado di fare nulla al riguardo.
Anni fa, quando sono diventato consapevole delle regex e sono andato oltre le basi per iniziare a essere fantasioso, sono stato in grado di creare alcuni schemi regex davvero orribilmente lenti.Molto dipende dal motore di regex, ma se stai lavorando con uno che supporta backreferences, lookaheads / lookbehind e / o avidi quantificatori, non è troppo difficile impantanare le cose.Ovviamente la lunghezza delle stringhe che stai cercando fa una grande differenza.L'espressione regolare su più righe su documenti di grandi dimensioni può davvero essere un cane.
@BoristheSpider [Questa domanda StackOverflow] (https://stackoverflow.com/questions/2733356/) sembra fornire un metodo per avviare le attività con un timeout.Non funziona in questo scenario?
@Nat si basa sul multitasking cooperativo - cioè annullerà (true) `il compito, che interromperà ()` il `Thread` - se il compito è interrompibile allora potrebbe funzionare, molto probabilmente non lo farà comunque.
Ecco un esempio di [un'espressione regolare che richiede tempi di esecuzione esponenziali su Java] (https://dzone.com/articles/how-kill-java-regular): `(0 *) * A`
L'unico caso "comune" di espressioni regolari dannose / lente di cui sono a conoscenza è solitamente chiamato [backtracking catastrofico] (https://www.regular-expressions.info/catastrophic.html).In particolare, non richiede alcuna funzionalità "avanzata", come lookahead / behind.
Ricordo che [SO una volta cadde anche a causa del backtracking delle regex] (http://stackstatus.net/post/147710624694/outage-postmortem-july-20-2016).
AJ Henderson
2018-08-06 07:31:07 UTC
view on stackexchange narkive permalink

La principale minaccia nell'accettare espressioni regolari sarà nel tuo motore di esecuzione regex piuttosto che accettare l'espressione regolare stessa. Mi aspetto che la minaccia sia molto, molto bassa in qualsiasi motore ben implementato. Il motore non dovrebbe aver bisogno di accedere a nessuna risorsa di sistema privilegiata e dovrebbe solo eseguire la logica sull'input fornito direttamente al motore. Ciò significa che anche se qualcuno trova un exploit nell'interprete, il danno che può essere fatto dovrebbe essere minimo.

Nel complesso, tutte le espressioni regolari è progettato per fare è cercare modelli all'interno di un valore. Finché viene seguita una protezione adeguata sui valori rispetto a cui si effettua il controllo, non c'è motivo per cui il motore stesso debba avere accesso per modificare i valori. Lo classificherei come generalmente abbastanza sicuro.

Detto questo, lo fornirei anche solo in situazioni in cui ha senso farlo. Regex è complesso, potenzialmente richiede tempo per essere eseguito e utilizzato nei posti sbagliati potrebbe avere alcuni impatti indesiderati su un'applicazione al di fuori di un contesto di sicurezza, ma nel giusto caso d'uso sono estremamente potenti e immensamente preziosi. (Sono un architetto di software che refactoring centinaia di migliaia di righe di codice regolarmente utilizzando regex.)

Questo non copre gli attacchi DoS tramite, ad esempio, backtracking catastrofico.
@boris Non ho considerato che una minaccia alla sicurezza come la costosa gestione di espressioni regolari in modo non interferente è necessaria anche nell'uso normale.Le persone faranno affermazioni regex eccessivamente complesse senza che si tratti di un attacco molto spesso.I timeout razionali sono una decisione di progettazione necessaria per motivi di prestazioni, non solo per la sicurezza.Sarebbe un po 'come dire che un rischio per la sicurezza nell'aggiunta di un report complesso è che le persone possono eseguire il DOS sul tuo sito eseguendo il report.Questo è un problema di prestazioni, non di sicurezza.
Le persone hanno bloccato i server con espressioni regolari e conosco personalmente un sito in cui centinaia di migliaia di utenti sono stati bloccati con quel tipo di costrutto.Non posso essere d'accordo sul fatto che tale danno sia minimo, poiché ci è voluto del tempo per rimetterlo online.
@eis hanno sfruttato il motore di regex o le guardie di sicurezza delle prestazioni non erano configurate correttamente e una serie di regex run away ha arrestato il server cercando di risolvere?Ho detto che il rischio di sfruttamento del motore è basso.Le query a esecuzione lenta, anche in un certo senso, sono un problema di prestazioni poiché query legittime potrebbero anche arrestare il server senza adeguate protezioni per la sicurezza delle prestazioni.
@AJHenderson hai ragione in quanto si tratta di quest'ultimo, non di sfruttare il motore.Tuttavia, anche senza alcun exploit, penso che l'impatto sull'utente finale potrebbe essere qualcosa di diverso dal minimo, anche se la regex non modificherà alcun valore.
@els - giusto, ma rileggi quello che ho detto nella risposta.Ho detto che i possibili impatti di un exploit sono minimi.Successivamente ho detto che possono durare molto a lungo e avere impatti potenzialmente indesiderati al di fuori del contesto della sicurezza.Poiché un input valido può anche comportare un carico di elaborazione sostanziale, considero le misure di salvaguardia delle prestazioni un problema di prestazioni piuttosto che di sicurezza.Certamente l'impatto di non disporre di protezioni di sicurezza adeguate per le prestazioni sarebbe catastrofico, anche per un uso legittimo.
PhilLab
2018-08-06 14:32:37 UTC
view on stackexchange narkive permalink

Come hanno sottolineato le altre risposte, il vettore di attacco sarebbe molto probabilmente il motore regex.

Anche se si presume che questi motori siano abbastanza maturi, robusti e accuratamente testati, è successo nel passato:

CVE-2010-1792 Esecuzione di codice arbitrario in Apple Safari e iOS. Citazione dalle note sulla patch:

Esiste un problema di danneggiamento della memoria nella gestione delle espressioni regolari da parte di WebKit. Visitare un sito web pericoloso può portare alla chiusura inaspettata dell'applicazione o all'esecuzione di codice arbitrario.

Ma ovviamente, l'argomento di una libreria potenzialmente difettosa vale per tutto, anche fornito dall'utente File JPEG.

L'altro aspetto, anche se non intrinsecamente tecnico, sarebbe il caso (. +) che hai citato: il prodotto dovrebbe consentire il recupero arbitrario dei dati?

Peter Green
2018-08-07 00:40:17 UTC
view on stackexchange narkive permalink

Il problema è che i motori regex "tornano indietro". Quando hai un'operazione di regex (es. + O *) nella tua regex, il motore di regex proverà a confrontarla con la maggior parte possibile della stringa di input. Se la corrispondenza in seguito fallisce, tornerà indietro e proverà ad abbinare la tua ripetizione a una parte più piccola della stringa di input.

Operazioni di ripetizioni multiple possono portare a un backtracking annidato e questo può portare al tempo di valutare l'espressione regolare che soffia in modo massiccio, soprattutto se gli operatori di ripetizione sono annidati.

https://www.regular-expressions.info/catastrophic.html

Non tutti i motori regex tornano indietro (anche se la maggior parte lo fa).L'alternativa al backtracking è considerare tutte le possibilità contemporaneamente finché non trovi quella che funziona.È più difficile da implementare ma evita i casi patologici.Vedi https://swtch.com/~rsc/regexp/regexp1.html
Tgr
2018-08-08 15:15:04 UTC
view on stackexchange narkive permalink

No, ReDoS non richiede che l'attaccante crei risultati di ricerca innaturali.

L'idea di base di ReDoS è che hai una sottoespressione che può corrispondere in più modi e corrispondere quasi ovunque nel campo di ricerca stringa tranne la fine, e si itera quella sottoespressione per ottenere un backtracking catastrofico. Quindi, ad esempio, se la descrizione del tuo negozio è Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. , puoi semplicemente usare qualcosa come ([^ q] | [^ q] [^ q]) + (o costrutti più complessi con ad esempio lookaheads).

Se questo è un problema dipende - come altre risposte hanno spiegato, puoi semplicemente limitare il tempo a disposizione del motore regex.

Vorrei menzionare che ci sono implementazioni regexp che non fanno il backtracking e quelle evitano questo problema.
RE2 è già menzionato in un'altra risposta.Tuttavia, non è davvero un'implementazione, è un sottoinsieme sicuro del linguaggio, quindi perderesti funzionalità rispetto a qualcosa come PCRE (probabilmente funzionalità di cui nessuno si preoccupa in un modulo di ricerca del prodotto).
Epiphany
2018-08-09 07:18:29 UTC
view on stackexchange narkive permalink

Risposta breve ... No. Indipendentemente dal fatto che si tratti di una regex o meno, si tratta comunque di dati forniti dall'utente e non dovrebbero MAI essere attendibili. La pratica standard è convalidare correttamente tutti i dati forniti dall'utente ... SEMPRE!”

Se desideri consentire l'uso di regex dall'utente, allora l'espressione regolare dell'utente deve essere confrontata con una lista bianca delle espressioni regolari consentite che desideri rendere disponibile per lo script. In questo modo non utilizzi mai direttamente la regex inviata dall'utente e, se non corrisponde a una regex nella whitelist, puoi uscire dallo script. L'unico modo sicuro per consentire regex come input dell'utente a cui posso pensare.

Non sono sicuro del motivo per cui questo è stato downvoted.Chi qui non è stato toccato dalla storia del piccolo [Bobby Tables] (https://www.xkcd.com/327/)?;)
Se desideri specificamente consentire all'utente di inserire un'espressione regolare arbitraria (considera un input di ricerca con un'opzione regex), questa risposta non è utile.Cosa significa convalidare una regex?Quali sono le conseguenze di non farlo?
Penso che sia abbastanza ingiusto votare la mia risposta, senza mostrare come intendi gestire questa regex una volta lato server, come nella mia soluzione perfettamente praticabile fornita nella mia risposta sopra.Se in qualche modo stai suggerendo di passare le espressioni regolari dell'utente (caricate con caratteri speciali) al tuo server senza convalida ... beh, buona fortuna!


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 4.0 con cui è distribuito.
Loading...