Egy reguláris kifejezés normál adaton azonnal lefuthat, egy gondosan választott inputon pedig másodpercekig vagy percekig fogyaszthat CPU-t. Katasztrofális backtracking akkor alakul ki, amikor a minta ugyanazt a szöveget sokféleképpen oszthatja fel, majd csak a végén bukik el. Az engine egyenként próbálja ki a kombinációkat. Nyilvános login, search vagy validation endpointnál ez denial-of-service kockázat.
A backtracking normál működés is lehet
A greedy quantifier először maximális részt fogyaszt, majd ha a következő token nem illeszkedik, karaktereket ad vissza. Ez teszi rugalmassá a mintát.
A veszély akkor jelenik meg, amikor több egymásba ágyazott vagy szomszédos rész ugyanazokat a karaktereket fogyaszthatja. Minden kudarc új ágakat nyit.
Az egymásba ágyazott ismétlés erős figyelmeztetés
Az (a+)+ sokféleképpen oszthatja fel ugyanazt az a-sorozatot. Ha a végén várt karakter hiányzik, az engine szinte minden felosztást kipróbál.
Valódi mintában ugyanezt optional whitespace, széles wildcard vagy átfedő alternatíva rejtheti el.
A választások legyenek megkülönböztethetők
Elválasztónál megálló character class egyértelműbb, mint dot-star és utána ugyanaz az elválasztó. Alternatívák lehetőleg különböző prefixszel kezdődjenek.
Atomic group és possessive quantifier megtilthatja a visszalépést, ha az engine támogatja. Csak valódi szemantikai döntést fejezzen ki.
A bemeneti limit az első védelmi réteg
Ha a felhasználónév legfeljebb 64 karakter, a hosszabb input regex előtt elutasítható. A limit a parsert, logot és adatbázist is védi.
Nagy dokumentum soronként vagy streamelve dolgozható fel egyetlen korlátlan pattern helyett. A limit nem javítja az exponenciális mintát, de csökkenti a maximális kárt.
A legrosszabb teszt majdnem helyes
Hosszú helyes prefix, hibás utolsó jel, hiányzó terminátor és ismételt delimiter szükséges. Az időt növekvő inputméretnél mérni kell.
A nem lineáris görbe figyelmeztetés akkor is, ha a kis fixture gyors. Fuzzing és analyzer kiegészítheti a kézi eseteket.
Nem minden engine ugyanúgy kockázatos
Egyes engine-ek lineáris időt garantálnak azzal, hogy nem támogatnak backreference-t és bizonyos konstrukciókat. Mások gazdagabbak, de patologikusan backtrackelhetnek.
Ugyanaz a source más runtime-ban eltérő profilt adhat. Framework-upgrade-hoz viselkedési és teljesítményteszt kell.
A ReDoS alkalmazásbiztonsági probléma
Támadó néhány drága requesttel elfoglalhat worker threadet vagy event loopot. A rate limit segít, de egyetlen illesztés is túllépheti a feltételezett költséget.
A védelem egyértelmű pattern, méretkorlát, timeout és szükség esetén izolált feldolgozás együttese.
A timeout korlátoz, de nem javít
A platform megszakíthatja a túl hosszú match-et. Az alkalmazás kontrollált hibát és metrikát adjon, ne próbálja automatikusan ugyanazt újra.
A gyakori timeout rossz patternre vagy inputmodellre utal. Nem elfogadható állandó működési mód.
A linear-time engine más trade-offot ad
Automataalapú engine a bemenet hosszával arányos időt garantálhat, de kisebb feature setet kínál. Nyilvános validációnál a kiszámíthatóság értékesebb lehet a backreference-nél.
Migrációkor a Unicode, anchor, capture és replacement eredményét össze kell vetni. A fordítható source még nem bizonyít azonos viselkedést.
Az observability a növekedést is mutassa
Dashboard mérheti a match latency percentilisét szabálynév és inputhossz-bucket szerint. Így a fokozatos romlás timeout előtt látszik.
A raw input ne legyen metric label. Request ID segítségével kontrollált logból lehet visszakeresni a körülményeket.
Az incident ideiglenes és végleges javítást kér
Támadás közben szigorítható a limit vagy kikapcsolható a problémás funkció. A tartós javítás eltávolítja az átfedő útvonalakat és regressziós benchmarkot ad.
A postmortem megkeresi a más szolgáltatásokba másolt mintát is. Egy shared utility több határon terjeszthette ugyanazt a kockázatot.
Néha a parser egyszerűbb
Ha hosszú bizonyítás kell ahhoz, hogy a quantifierek nem fedik egymást, determinisztikus parser olvashatóbb és biztonságosabb lehet. Doménhibákat is jobban ad.
A backtracking nem ok a regex elutasítására. Arra kötelez, hogy a mintát futtatható kódként kezeljük, ellenséges hibákon teszteljük és világos határokat adjunk neki.
A biztonsági review a teljes adatútvonalat követi
Ugyanaz a pattern rövid mezőn biztonságos, teljes request body fölött veszélyes lehet. A review megvizsgálja a bemenet forrását, a megelőző decode-ot, a maximális méretet és a hívás gyakoriságát.
A költség már a regex előtt is jelentkezhet: egy óriási compressed vagy encoded string kicsomagolása és másolása erőforrást fogyaszt. A védelem HTTP limittől az alkalmazási timeoutig több rétegből áll.
A performance regression CI-ben is mérhető
Microbenchmark növekvő, majdnem illeszkedő inputokkal fut. Nem kell minden buildben pontos milliszekundumot garantálni, de a nagyságrendi vagy nem lineáris romlás észlelhető. A benchmark ugyanazt az engine-t és flags-et használja, mint a produkció.
A timeoutteszt önmagában kevés, mert csak a végső határt látja. A növekedési görbe korábban jelzi, ha egy új alternatíva több visszalépési utat nyitott.
A produkciós incidens után osztályszintű javítás kell
Egy konkrét támadó string tiltása nem oldja meg a kétértelmű mintát. A végleges változtatás újraszervezi a határokat, limitet ad, és tesztet készít a problémás szerkezetről több hosszban.
A kódbázisban meg kell keresni a pattern vagy fragment másolatait. Egy shared snippet ugyanazt a ReDoS kockázatot több endpointon is terjesztheti.
A determinisztikus parser jobb hibát adhat
Ha a bemenet elválasztókkal és állapotokkal világosan feldolgozható, egy kis parser lineáris utat és konkrét hibahelyet ad. Nem kell bizonyítani, hogy egymásba ágyazott quantifierek minden esetben kizárják egymást.
A regex továbbra is jó tokenek és lokális formák felismerésére. A cél nem az elkerülése, hanem a megfelelő absztrakció kiválasztása a fenyegetés és karbantartási költség alapján.