Düzenli İfade Hizmet Reddi'nin (ReDoS) farkındayım. Kullanıcıların, katlanarak yavaş bir kalıp göndermediklerini garanti ederken özel regex'ler oluşturmasına izin vermenin makul bir yolu var mı?
Düzenli İfade Hizmet Reddi'nin (ReDoS) farkındayım. Kullanıcıların, katlanarak yavaş bir kalıp göndermediklerini garanti ederken özel regex'ler oluşturmasına izin vermenin makul bir yolu var mı?
Yanıtlar:
Düzenli ifadelerle ilgili sorun normal ifadenin kendisi değil, geri izleme gibi her türlü “kullanışlı” özelliğe sahip normal ifade motorudur. Bu nedenle, bu özelliklere sahip olmayan bir regex motoru kullanmaktan kaçınır.
Bilgisayar bilimi kavramının düzenli ifadeleri, sonlu durum makinesine derlendikten sonra daima doğrusal zamanda eşleştirilebilir. Dolayısıyla, durum makinesi tabanlı bir normal ifade motoru ReDoS için kullanılamaz. Bununla birlikte, gerekli durum makineleri patolojik örneklerde oldukça büyük olabilir. Ancak kullanılabilir belleği sınırlamak, kullanılabilir hesaplama süresini sınırlamaktan daha kolay olma eğilimindedir.
RE2 motoru güvenilmeyen regexes başa özel olarak geliştirilen ve lineer zamanı yürütülmesi için tasarlanmıştır.
Başka bir alternatif, regex'leri basitleştirilmiş bir gösterimle birleştirmektir. Örneğin, kullanıcıların glob kalıplarını (örneğin *.txt
) kullanmasına izin verebilirsiniz . Daha sonra, örneğin iç içe yerleştirmeye izin vermeyerek ve sadece açgözlü niceleyiciler kullanarak geri izlemeyi önleyecek şekilde ayrıştırabilirsiniz. Birçok kullanım durumunda, basitleştirilmiş bir desen gösterimi tamamen yeterlidir.
Düzenli bir ifadenin analizinin kendisi yavaşlamadan yavaş olup olmayacağını görmek için durma problemini çözmek anlamına gelir. Başka bir deyişle, doğru ve eksiksiz bir çözüm bulmak mümkün değildir .
Elbette, doğru ve bir çözüm bulabilirsiniz içinde tamamlandı. Örneğin, kullanımı güvenli özelliklerin kısıtlayıcı bir beyaz listesiyle çalışabilirsiniz (örneğin, karakter sınıfları evet, tekrar no ...). Bu, çok sayıda eleştirel olmayan regex'i geçirmenize, tüm kritik olanları reddetmenize ve (yanlış) iyi, ancak otomatik olarak güvenli olduğunu kanıtlamak için çok karmaşık olan bazılarını reddetmenize izin verecektir.
Lazarus projesinin yeniden ayrıştırıcısının yazarı olarak, herhangi bir düzenli ifadeyi belirli bir metinde hangi kaynakları tüketeceğini anlamanın hiçbir yolu olmadığını söyleyebilirim.
Aynı kaynakları harcamadan demek istiyorum (en azından big-O anlamında).
Bu yüzden en iyi yaklaşım - ayrıştırıcıyı ayrı bir iş parçacığında yeniden çalıştırın ve zaman aşımından sonra öldürün.
Diğer cevaplara ek olarak, kendi regex kütüphanenizi yürütmek, yürütme sırasında performans enstrümantasyonuna izin vermek ve böylece bazı kriterler karşılandığında yürütmeyi yarıya indirmek için araçlar sağlamak için bir çözüm de olabilir.
Benzer şekilde, regexes'i başka bir iş parçacığında çalıştırabilir ve çok uzun sürerse iş parçacıklarını öldürebilirsiniz.