Normal bir ifadeye kötü amaçlı kod koymanın bir yolu var mı?


138

Herkese açık web sayfama düzenli ifade arama özelliği eklemek istiyorum. Çıktıyı kodlayan HTML dışında , kötü niyetli kullanıcı girişine karşı koruma sağlamak için herhangi bir şey yapmam gerekir mi?

Google aramaları zararlı girişini tespit etmek için düzenli ifadeler kullanarak sohbet problem-- çözme insanlar tarafından gömülmek -. Ben ilgilenen değilim benim senaryoda, kullanıcı girişi olan bir normal ifade.

.NET (C #) Regex kitaplığını kullanacağım .


4
Bu, hangi dili ve / veya normal regex kütüphanesini kullandığınıza bağlı olabilir.
aschepler

Yanıtlar:


216

Hizmet Reddi Endişeleri

Regexes ile ilgili en yaygın endişe, üstel olan - hatta süper üslü olan patolojik örüntülerle reddedilen bir hizmet attack saldırısıdır! - ve böylece çözülmesi sonsuza dek sürecek gibi görünüyor. Bunlar yalnızca belirli girdi verilerinde görünebilir, ancak genellikle bunun önemli olmadığı bir veri yaratılabilir.

Bunlardan hangileri kullandığınız regex derleyicisinin ne kadar akıllı olduğuna bağlı olacaktır, çünkü bunların bazıları derleme sırasında tespit edilebilir. Özyineleme uygulayan Regex derleyicilerinde ilerlemenin kontrol edilmemesi için yerleşik bir özyineleme derinliği sayacı vardır.

Russ Cox'un Düzenli İfade Eşleştirmesi hakkındaki 2007 tarihli mükemmel makalesi Basit ve Hızlı Olabilir (ancak Java, Perl, PHP, Python, Ruby, ... 'de yavaştır), hepsi de modern bir SpFA'nın Henry Spencer'in kodundan türemiş gibi görünen yollarından bahseder , ciddi performans düşüşü yaşar, ancak Thompson tarzı bir NFA'nın böyle bir sorunu yoktur.

Yalnızca DFA'lar tarafından çözülebilecek kalıpları kabul ederseniz, bunları bu şekilde derleyebilirsiniz ve bunlar daha hızlı, muhtemelen çok daha hızlı çalışır. Ancak, bunu yapmak zaman alır . Cox makalesinde bu yaklaşımdan ve beraberindeki sorunlardan bahsedilmektedir. Her şey klasik bir zaman-uzay değiş tokuşuna dönüşüyor.

Bir DFA ile, onu oluşturmak için daha fazla zaman harcarsınız (ve daha fazla eyalet tahsis eder), oysa bir NFA ile onu yürütmek için daha fazla zaman harcarsınız, çünkü aynı anda birden fazla durum olabilir ve geri izleme öğle yemeğinizi ve CPU'nuzu yiyebilir.

Reddetme ‐ Hizmet Çözümleri

Evrenin sıcak ölümüyle bir yarışın kaybedilen ucundaki bu kalıpları ele almanın muhtemelen en makul yolu, onları, çalıştırılmaları için izin verilen maksimum süreyi etkili bir şekilde yerleştiren bir zamanlayıcı ile sarmaktır. Genellikle bu, çoğu HTTP sunucusunun sağladığı varsayılan zaman aşımından çok, çok daha az olacaktır.

Bunları uygulamak alarm(N)için, C düzeyinde basit bir form try {}, yakalama alarmı tipi istisnaları bir tür bloğa kadar, içine yerleştirilmiş bir zamanlama kısıtlamasıyla özel olarak oluşturulmuş yeni bir iş parçacığını ortaya çıkarmanın çeşitli yolları vardır .

Kod Ek Bilgileri

Kod Ek bilgileri itiraf regex dillerde, izin veya derleme gidiyoruz dizesinden bu izin vermeme bazı mekanizma olmalıdır sağlanacaktır. Kod bilgileri yalnızca kullandığınız dilde kodlanacak olsa bile, bunları kısıtlamanız gerekir; harici kod çağırabilmeleri gerekmiyor, ancak yapabiliyorlarsa çok daha büyük sorunlarınız var.

Örneğin, Perl'de use re "eval";, geçerli kapsamda etkin olan özel olarak sözcüksel olarak hazırlanmış pragma olmadıkça, dize enterpolasyonundan oluşturulan regex'lerde kod belirtme çizgileri olamaz (bunlar çalışma zamanında derlendiği gibi) .

Bu şekilde, hiç kimse, rm -rf *örneğin sistem programlarını çalıştırmak için bir kod bilgisine gizlice giremez . Kod açıklamaları güvenlik açısından çok hassas olduğundan, Perl bunları enterpolasyonlu dizelerde varsayılan olarak devre dışı bırakır ve bunları yeniden etkinleştirmek için kendi yolunuzdan çıkmanız gerekir.

Kullanıcı ined Tanımlı \ P {roperties}

Gibi - Unicode tarzı özelliklerine ilişkin bir tane daha güvenlik-hassas bir konu var olmaya devam \pM, \p{Pd}, \p{Pattern_Syntax}, veya \p{Script=Greek}- o olabilir bazı regex derleyici desteğin o notasyonu var.

Sorun, bunlardan bazılarında olası özellikler kümesinin kullanıcı tarafından genişletilebilir olmasıdır. Bu, \p{GoodChars}veya gibi bazı belirli ad alanlarında adlandırılmış işlevlere gerçek kod belirtimleri olan özel özelliklere sahip olabileceğiniz anlamına gelir \p{Class::Good_Characters}. Dilinizin bunları nasıl ele aldığına bakmaya değer olabilir.

Korumalı

Perl'de, Safemodül aracılığıyla korumalı bir bölme, ad alanının görünürlüğü üzerinde kontrol sağlayacaktır. Diğer diller de benzer sanal alan teknolojileri sunmaktadır. Bu tür aygıtlar varsa, bunlara bakmak isteyebilirsiniz, çünkü bunlar güvenilmeyen kodun sınırlı yürütülmesi için özel olarak tasarlanmıştır.


4
NFA-> DFA dönüşümü, zamanın DoS'unu bir boşluk DoS'a dönüştürerek üstel durum patlaması ve üstel durum üretme zaman maliyetine neden olabilir.
Barry Kelly

ama muhtemelen normal ifadelerin tüm özelliklerine ihtiyaç duymayacaktır, google gibi normal ifadelerin gücünü kısıtlama hakkında ne düşünüyorsunuz: google.com/intl/tr/help/faq_codesearch.html#regexp
systemsfault

1
@Barry Oldukça doğru. Russ Cox'un NFA'nın bölümlerini kademeli olarak eşdeğer bir DFA'ya derleyen makalelerinden birinde açıklanan stratejisini düşünüyordum ama çok büyüdüğünde fırlatıyordu. Ancak DFA'da gümüş mermi yoktur, hatta Thompson bunu bir NFA'ya eşdeğer kanıtlamış olsa bile, çünkü piperi bir noktada ya da başka bir noktada ödemek zorundasınız. Daha fazla alan için işletim sistemine yalvarmak için harcanan zaman ve ilgili sayfa tablosu kurulum maliyetleri bazen dengeleme ölçeğini başka bir şekilde daha fazla sürükleyebilir ve zamandan uzaya dönüşümü olması gerekenden daha az çekici hale getirebilir.
tchrist

20

Tchrist'in mükemmel cevabına ek olarak: "Normal İfade" sayfasını yazan aynı Russ Cox da kod yayınladı! re2 , O (length_of_regex) çalışma zamanını ve yapılandırılabilir bellek kullanım sınırını garanti eden bir C ++ kütüphanesidir. Google'da, Google kod aramasına bir normal ifade yazabilmeniz için kullanılır - yani savaşta test edilmiştir.


2
Gerçekten de öyle. Re2'yi Perl'in normal regex motoruna bir modülle takas edebilirsiniz ve mümkünse re2 ve değilse Perl kullanır. Oldukça iyi çalışıyor.
tchrist


6

Bu makaleyi okumak isteyeceksiniz:

Güvensiz Bağlam Değiştirme: Hayatta kalmak için düzenli ifadeleri aşılama Kağıt, normal ifade motorlarında (örneğin PCRE) neyin yanlış gidebileceğiyle ilgili daha fazla bilgi verir, ancak neyle karşı karşıya olduğunuzu anlamanıza yardımcı olabilir.


1
İşte GNU libc regcomp (3) koduyla ilgili bir güvenlik danışma belgesi: securityreason.com/achievement_securityalert/93 Ne kadar zamanında! En azından linux altında, güvenlik açığının gösterilmesi kolaydır: grep -E ". * {10,} {10,} {10,} {10,} {10,}"
Bruce Ediger

5

Sadece eşleşmenin kendisi için değil, eşleştirmeyi nasıl yaptığınız konusunda da endişelenmeniz gerekir. Örneğin, girdiniz normal ifade motoruna giderken bir çeşit değerlendirme aşaması veya komut değiştirme işleminden geçiyorsa, model içinde yürütülen kod olabilir. Veya, normal ifade sözdiziminiz gömülü komutlara izin veriyorsa, buna da dikkat etmelisiniz. Sorunuzdaki dili belirtmediğiniz için, tüm güvenlik etkilerinin ne olduğundan emin olmak zor.


1

RegEx'lerinizi güvenlik sorunları (en azından Windows için) açısından test etmenin iyi bir yolu, Microsoft tarafından son zamanlarda yayınlanan SDL RegEx tüylenme aracıdır . Bu patolojik olarak kötü RegEx yapısını önlemeye yardımcı olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.