मैं एक दुष्ट रेगेक्स को कैसे पहचान सकता हूं?


84

मुझे हाल ही में सेवा अभिव्यक्ति के नियमित अभिव्यक्ति से अवगत कराया गया , सेवा हमलों से इनकार किया, और जहां कहीं भी मुझे अपने कोडबेस में - या कम से कम उन जो उपयोगकर्ता इनपुट पर उपयोग किए जाते हैं, तथाकथित 'बुराई' रेगेक्स पैटर्न को जड़ से उखाड़ने का फैसला किया। उपरोक्त OWASP लिंक और विकिपीडिया पर दिए गए उदाहरण सहायक हैं, लेकिन वे सरल शब्दों में समस्या को समझाने का एक बड़ा काम नहीं करते हैं।

विकिपीडिया से, दुष्ट रेगीज़ का विवरण :

  • नियमित अभिव्यक्ति दोहराव ("+", "*") एक जटिल उपसंचाई पर लागू होती है;
  • बार-बार होने वाले सब-डेप्रिसिएशन के लिए, एक मैच मौजूद होता है जो दूसरे वैध मैच का एक प्रत्यय भी होता है।

उदाहरण के साथ, विकिपीडिया से फिर से :

  • (a+)+
  • ([a-zA-Z]+)*
  • (a|aa)+
  • (a|a?)+
  • (.*a){x} x> 10 के लिए

क्या यह एक ऐसी समस्या है जिसका सरल स्पष्टीकरण नहीं है? मैं एक ऐसी चीज की तलाश कर रहा हूं, जो कि रेग्जेस लिखते समय, या मौजूदा कोडबेस के भीतर उन्हें खोजने में इस समस्या से बचने में आसान हो।


7
इस विषय के बारे में एक और कड़ी यह है: regular-expressions.info/catastrophic.html
डैनियल हिल्गारथ

1
यहां संदिग्ध ReDoS समस्याओं की खोज के लिए नियमित अभिव्यक्तियों पर स्थिर विश्लेषण करने के लिए एक उपकरण है: cs.bham.ac.uk/~hxt/research/rxxr.shtml
tripleee

@Tripleee द्वारा प्रदान किया गया लिंक RXXR टूल के लिए एक टूटी हुई लिंक है। यहाँ एक GitHub दर्पण है: github.com/ConradIrwin/rxxr2
माइक हिल

3
इसके अतिरिक्त, उन उत्सुक लोगों के लिए, यह मूल आरएक्सआरआर टूल के लेखकों की तरह दिखता है, जिन्होंने इसे आरएक्सआरआर 2 के साथ जोड़ दिया। उनका नया पृष्ठ यहाँ होस्ट किया गया है और वर्तमान में RXXR2 स्रोत के लिए एक लिंक काम कर रहा है: cs.bham.ac.uk/~hxt/research/rxxr2
माइक हिल

जवाबों:


77

ईविल रेग्जेस एक समस्या क्यों हैं?

क्योंकि कंप्यूटर वास्तव में वही करते हैं जो आप उन्हें करने के लिए कहते हैं, भले ही वह वही न हो जिसका आपका मतलब था या पूरी तरह से अनुचित है। यदि आप एक रेगेक्स इंजन को यह साबित करने के लिए कहते हैं कि, कुछ दिए गए इनपुट के लिए, दिए गए पैटर्न के लिए मैच है या नहीं है, तो इंजन यह करने का प्रयास करेगा कि कोई फर्क नहीं पड़ता कि कितने विभिन्न संयोजनों का परीक्षण किया जाना चाहिए।

यहाँ ओपी के पद में पहले उदाहरण से प्रेरित एक सरल पैटर्न है:

^((ab)*)+$

इनपुट दिया:

abababababababababababab

रेगेक्स इंजन कुछ इस तरह की कोशिश करता है (abababababababababababab)और पहली कोशिश में एक मैच मिलता है।

लेकिन फिर हम बंदर रिंच में फेंक देते हैं:

abababababababababababab एक

इंजन पहले प्रयास करेगा (abababababababababababab)लेकिन उस अतिरिक्त के कारण विफल हो जाता है a। यह भयावह कोष्ठक का कारण बनता है, क्योंकि हमारे पैटर्न (ab)*, अच्छे विश्वास के एक शो में, इसमें से एक को कैप्चर (यह "बैकट्रैक") जारी करेगा और बाहरी पैटर्न को फिर से प्रयास करने देगा। हमारे रेगेक्स इंजन के लिए, जो कुछ इस तरह दिखता है:

(abababababababababababab)- नोप
(ababababababababababab)(ab)- नोप
(abababababababababab)(abab)- नोप
(abababababababababab)(ab)(ab)- नोप
(ababababababababab)(ababab)- नोप
(ababababababababab)(abab)(ab)- नोप
(ababababababababab)(ab)(abab)- नोप
(ababababababababab)(ab)(ab)(ab)- नोप
(abababababababab)(abababab)- नोप
(abababababababab)(ababab)(ab)- नोप
(abababababababab)(abab)(abab)-
(abababababababab)(abab)(ab)(ab)नोप
(abababababababab)(ab)(ababab)- नोप
(abababababababab)(ab)(abab)(ab)- नोप
(abababababababab)(ab)(ab)(abab)- नोप
(abababababababab)(ab)(ab)(ab)(ab)- नोप
(ababababababab)(ababababab)- नोप
(ababababababab)(abababab)(ab)- नोप
(ababababababab)(ababab)(abab)- नोप
(ababababababab)(ababab)(ab)(ab)- नोप
(ababababababab)(abab)(abab)(ab)- नोप
(ababababababab)(abab)(ab)(abab)- नोप
(ababababababab)(abab)(ab)(ab)(ab)- नोप
(ababababababab)(ab)(abababab)- नोप
(ababababababab)(ab)(ababab)(ab)- नोप
(ababababababab)(ab)(abab)(abab)- नहीं
(ababababababab)(ab)(abab)(ab)(ab)- नहीं
(ababababababab)(ab)(ab)(ababab)- नहीं
(ababababababab)(ab)(ab)(abab)(ab)- नहीं
(ababababababab)(ab)(ab)(ab)(abab)- नहीं
(ababababababab)(ab)(ab)(ab)(ab)(ab)- नहीं
                              ...
(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ab)(abababab) - नहीं
(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ababab)(ab)- नहीं
(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ab)(abab)(abab)- नहीं
(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ab)(abab)(ab)(ab)- नहीं
(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ababab)- नहीं
(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ab)(abab)(ab)- नहीं
(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ab)(abab)- नहीं
(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ab)(ab)- नहीं - नहीं - नहीं

इनपुट की लंबाई के साथ संभावित संयोजनों की संख्या तेजी से बढ़ती है और, इससे पहले कि आप इसे जानते हैं, रेगेक्स इंजन आपके सभी सिस्टम संसाधनों को खा रहा है जब तक कि इस चीज को हल करने की कोशिश की जा रही है, जब तक कि शर्तों के हर संभव संयोजन को समाप्त नहीं हो जाता, यह अंत में छोड़ देता है। रिपोर्ट "कोई मेल नहीं है।" इस बीच आपका सर्वर पिघले हुए धातु के जलते हुए ढेर में बदल गया है।

ईविल रेगेक्स को कैसे स्पॉट करें

यह वास्तव में बहुत मुश्किल है। मैंने खुद एक युगल लिखा है, भले ही मुझे पता है कि वे क्या हैं और आम तौर पर उनसे कैसे बचा जाए। रेगेक्स को आश्चर्यजनक रूप से लंबे समय तक लेते हुए देखें । एक परमाणु समूह में आप जो कुछ भी कर सकते हैं उसे लपेटकर बैकट्रैकिंग मुद्दे को रोकने में मदद कर सकते हैं। यह मूल रूप से रेगेक्स इंजन को किसी दिए गए एक्सप्रेशन को फिर से प्रदर्शित नहीं करने के लिए कहता है - "जो भी आप पहली कोशिश में मिलान करते हैं उसे लॉक करें"। ध्यान दें, हालांकि, परमाणु अभिव्यक्तियाँ अभिव्यक्ति के भीतर पीछे जाने से नहीं रोकती हैं , इसलिए ^(?>((ab)*)+)$यह अभी भी खतरनाक है, लेकिन ^(?>(ab)*)+$यह सुरक्षित है (यह मेल खाएगा (abababababababababababab)और फिर मिलान किए गए वर्णों में से किसी को भी देने से इनकार कर देगा, इस प्रकार भयावह बैकट्रैकिंग को रोकना)।

दुर्भाग्य से, एक बार यह लिखे जाने के बाद, यह वास्तव में तुरंत या बहुत जल्दी एक समस्या regex खोजने के लिए बहुत कठिन है। अंत में, एक खराब रेगेक्स को पहचानना किसी अन्य बुरे कोड को पहचानने जैसा है - इसमें बहुत समय और अनुभव और / या एक भी विपत्तिपूर्ण घटना होती है।


दिलचस्प बात यह है कि चूंकि यह उत्तर पहली बार लिखा गया था, ऑस्टिन के टेक्सास विश्वविद्यालय में एक टीम ने इन "बुराई" पैटर्न को खोजने के व्यक्त उद्देश्य के साथ नियमित अभिव्यक्तियों के स्थैतिक विश्लेषण करने में सक्षम उपकरण के विकास का वर्णन करते हुए एक पेपर प्रकाशित किया था। जावा प्रोग्राम्स का विश्लेषण करने के लिए टूल विकसित किया गया था, लेकिन मुझे संदेह है कि आने वाले वर्षों में हम जावास्क्रिप्ट और अन्य भाषाओं में एनालाइजिंग और समस्याग्रस्त पैटर्नों के आसपास विकसित किए गए अधिक टूल देखेंगे, विशेष रूप से जब तक कि ReDoS हमलों की दर चढ़ाई जारी है

कार्यक्रमों में DoS कमजोरियों की स्थैतिक पहचान जो रेगुलर एक्सप्रेशंस वाले
वेलेंटीन वुस्टहोलज़, ओस्वाल्डो ओलिवो, मेराज जेएच हेउल और
ऑस्टिन में टेक्सास विश्वविद्यालय के आइल डिलिग का उपयोग करती है


यह वर्णन करने में एक बहुत अच्छा जवाब है / क्यों / उदाहरण रेगेक्स में एक लंबा समय लगता है, लेकिन मैं कुछ नियमों की तलाश कर रहा हूं जो किसी व्यक्ति को समस्या रेगेक्स को पहचानने में मदद करने के लिए आंतरिक कर सकते हैं।
माइक पार्ट्रिज

4
"क्यों" जानना एक "बुराई" रेगेक्स लिखने से बचने की दिशा में सबसे महत्वपूर्ण कदम है। दुर्भाग्य से, एक बार लिखे जाने के बाद, यह वास्तव में बहुत मुश्किल से तुरंत या जल्दी से एक समस्या regex खोजने के लिए है। यदि आप एक कंबल फिक्स चाहते हैं, तो परमाणु समूहन आमतौर पर सबसे अच्छा तरीका है, लेकिन यह उस पैटर्न पर एक महत्वपूर्ण प्रभाव डाल सकता है जो रेगेक्स मैच करेगा। अंत में, एक खराब रेगेक्स को पहचानना किसी भी अन्य बुरे कोड को regex की तरह है - यह बहुत अनुभव, बहुत समय और / या एक भयावह घटना लेता है।
JDB आज भी

यही कारण है कि मेरी प्राथमिकता रेगेक्स इंजनों के लिए है जो उपयोगकर्ता को मजबूर किए बिना बैकट्रैकिंग का समर्थन नहीं करते हैं। आईई लेक्स / फ्लेक्स।
स्पेंसर रथबुन

@MikePartridge यह सामान्य आईटी क्लासिक थ्योरी समस्या है, यह तय करने के लिए कि कुछ कोड अनंत रूप से लूप करेगा या स्टॉप एनपी-पूर्ण तरह की समस्या है। Regexes के साथ आप निश्चित पैटर्न / नियमों की खोज करके उनमें से कुछ का अनुमान लगा सकते हैं / पकड़ सकते हैं, लेकिन जब तक आप कुछ भारी एनपी-पूर्ण विश्लेषण नहीं करते, आप उन सभी को कभी नहीं पकड़ पाएंगे। कुछ विकल्प: 1) उपयोगकर्ता को अपने सर्वर पर regexp दर्ज करने की अनुमति न दें। 2) गणना को जल्दी समाप्त करने के लिए regexp इंजन को कॉन्फ़िगर करें (लेकिन अपने कोड में अपने मान्य regex का परीक्षण अभी भी, कड़े सीमाओं के साथ भी करें)। 3) सीपीयू / मेम सीमा के साथ कम-प्राथमिकता वाले धागे में रेगेक्स कोड चलाएं।
पेड

1
@ मायकपार्ट्रिज - हाल ही में एक कागज पर कुछ नए औजारों के बारे में आया है जो कि इन समस्याग्रस्त रेगीक्स का सांख्यिकीय रूप से पता लगाने के लिए विकसित किए जा रहे हैं। दिलचस्प सामान ... मुझे लगता है कि यह निम्नलिखित के लायक होगा।
JDB को अभी भी

12

जिसे आप "बुराई" रेगेक्स कहते हैं, एक रेगीक्स है जो भयावह बैकट्रैकिंग को प्रदर्शित करता है । लिंक किए गए पृष्ठ (जो मैंने लिखा था) अवधारणा को विस्तार से बताता है। असल में, भयावह बैकट्रैकिंग तब होती है जब एक रेगेक्स मैच करने में विफल रहता है और एक ही रेगेक्स के विभिन्न क्रमांकन एक आंशिक मैच पा सकते हैं। रेगेक्स इंजन फिर उन सभी क्रमपरिवर्तन की कोशिश करता है। यदि आप अपने कोड पर जाना चाहते हैं और अपने regexes का निरीक्षण करते हैं तो ये 3 मुख्य मुद्दे हैं:

  1. वैकल्पिक रूप से अनन्य होना चाहिए। यदि कई विकल्प एक ही पाठ से मेल खा सकते हैं, तो इंजन दोनों की कोशिश करेगा यदि रेगेक्स का शेष विफल रहता है। यदि विकल्प एक समूह में हैं जो दोहराया जाता है, तो आपके पास विनाशकारी बैकट्रैकिंग है। एक क्लासिक उदाहरण (.|\s)*किसी भी पाठ की किसी भी राशि से मेल खाना है जब रेगेक्स स्वाद में "डॉट मैच लाइन ब्रेक" मोड नहीं है। यदि यह एक लंबे समय तक regex का हिस्सा तो एक पर्याप्त लंबी (दोनों के अनुरूप रिक्त स्थान की चलाने के साथ एक विषय स्ट्रिंग है .और \s) regex टूट जाएगा। यह (.|\n)*विकल्प वैकल्पिक रूप से अनन्य बनाने के लिए उपयोग करने के लिए या इससे भी अधिक विशिष्ट होने के लिए बेहतर है जिसके बारे में पात्रों को वास्तव में अनुमति दी जाती है, जैसे कि [\r\n\t\x20-\x7E]ASCII प्रिंटबेल, टैब और लाइन ब्रेक।

  2. क्रमबद्ध मात्रा वाले टोकनों को या तो एक दूसरे के साथ परस्पर अनन्य होना चाहिए या परस्पर अनन्य होना चाहिए जो उनके बीच आता है। अन्यथा दोनों एक ही पाठ से मेल खा सकते हैं और दो मात्रात्मक के सभी संयोजनों की कोशिश की जाएगी जब शेष रेगेक्स मेल करने में विफल रहता है। एक क्लासिक उदाहरण a.*?b.*?cउनके बीच "कुछ भी" के साथ 3 चीजों का मिलान करना है। जब cपहली बार मिलान नहीं किया जा सकता .*?है तो रेखा या फ़ाइल के अंत तक चरित्र द्वारा चरित्र का विस्तार होगा। प्रत्येक विस्तार के लिए दूसरा .*?वर्ण द्वारा वर्ण का विस्तार करेगा शेष रेखा या फ़ाइल से मिलान करने के लिए। यह तय है कि आपको उनके बीच "कुछ भी" नहीं हो सकता है। पहले रन को रोकने की जरूरत है bऔर दूसरे रन को रोकने की जरूरत है c। एकल पात्रों के साथa[^b]*+b[^c]*+cएक आसान उपाय है। चूंकि अब हम सीमांकक पर रोकते हैं, हम प्रदर्शन को और बढ़ाने के लिए अधिकारवादी मात्रा का उपयोग कर सकते हैं।

  3. एक समूह जिसमें एक क्वांटिफायर के साथ एक टोकन होता है, उसके पास खुद का एक क्वांटिफायर नहीं होना चाहिए, जब तक कि समूह के भीतर निर्धारित मात्रा को केवल किसी और चीज के साथ मिलान नहीं किया जा सकता है जो इसके साथ पारस्परिक रूप से अनन्य है। यह सुनिश्चित करता है कि आंतरिक क्वांटिफायर के अधिक पुनरावृत्तियों वाले बाहरी क्वांटिफायर के कम पुनरावृत्तियों का कोई ऐसा तरीका नहीं है जो आंतरिक क्वांटिफायर के कम पुनरावृत्तियों के साथ बाहरी क्वांटिफायर के अधिक पुनरावृत्तियों के समान पाठ से मेल खा सके। यह JDB के उत्तर में चित्रित समस्या है।

जब मैं अपना उत्तर लिख रहा था तब मैंने फैसला किया कि इसने मेरी वेबसाइट पर एक पूरा लेख मिला दिया । यह अब ऑनलाइन भी है।


10

मैं इसे "एक पुनरावृत्ति की पुनरावृत्ति" के रूप में लिखूंगा। आपके द्वारा सूचीबद्ध पहला उदाहरण एक अच्छा एक है, क्योंकि यह बताता है कि "एक पंक्ति में एक, एक या अधिक बार। यह फिर से एक पंक्ति में एक या अधिक बार हो सकता है"।

इस मामले में देखने के लिए क्या मात्राओं का संयोजन है, जैसे * और +।

बाहर देखने के लिए एक और अधिक सूक्ष्म बात तीसरी और चौथी है। उन उदाहरणों में एक OR ऑपरेशन होता है, जिसमें दोनों पक्ष सत्य हो सकते हैं। यह अभिव्यक्ति के एक मात्रा के साथ संयुक्त इनपुट स्ट्रिंग के आधार पर संभावित मैचों के बहुत सारे में परिणाम कर सकते हैं।

इसे योग करने के लिए, TLDR- शैली:

सावधान रहें कि अन्य ऑपरेटरों के साथ संयोजन में क्वांटिफायर का उपयोग कैसे किया जाता है।


3
वर्तमान में, यह उत्तर उस चीज के सबसे करीब आता है जिसकी मुझे तलाश है: एक रेक्स को पहचानने के लिए अंगूठे का एक नियम जो भयावह फैलने का कारण बन सकता है।
माइक पार्टरिज

1
आपने जो छोड़ा था, और जो समस्या का एक महत्वपूर्ण हिस्सा प्रतीत हो रहा है, वह समूहों पर कब्जा कर रहा है।
माइक पार्टरिज

@ माइकपार्ट्रिज भी। मैंने इसे जितना संभव हो उबालने की कोशिश की, इसलिए अन्य चीजें हैं जो समान चीजों का कारण बन सकती हैं, जैसे समूहों पर कब्जा करना।
जरमुंड

7

मैं आश्चर्यजनक रूप से ReDOS के पार आया हूं, जो कई बार सोर्स कोड रिव्यू करता है। एक बात जो मैं सुझाऊँगा कि आप जो भी रेग्युलर एक्सप्रेशन इंजन इस्तेमाल कर रहे हैं उसके साथ एक टाइमआउट का उपयोग करें।

उदाहरण के लिए, C # में मैं एक TimeSpanविशेषता के साथ नियमित अभिव्यक्ति बना सकता हूं ।

string pattern = @"^<([a-z]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)$";
Regex regexTags = new Regex(pattern, RegexOptions.None, TimeSpan.FromSeconds(1.0));
try
{
    string noTags = regexTags.Replace(description, "");
    System.Console.WriteLine(noTags);
} 
catch (RegexMatchTimeoutException ex)
{
    System.Console.WriteLine("RegEx match timeout");
}

यह रेगेक्स सेवा से वंचित करने के लिए असुरक्षित है और बिना टाइमआउट स्पिन और संसाधनों को खाएगा। टाइमआउट के साथ, यह RegexMatchTimeoutExceptionदिए गए टाइमआउट के बाद फेंक देगा और संसाधन के उपयोग से इनकार नहीं करेगा जिससे सेवा की स्थिति से इनकार किया जा सकेगा।

आप यह सुनिश्चित करने के लिए टाइमआउट मान के साथ प्रयोग करना चाहेंगे कि यह आपके उपयोग के लिए काम करता है।


7

बुराई regexes का पता लगाना

  1. निकोलास वेइडमैन की रेग्जस्टैटिक एनलिसिस परियोजना का प्रयास करें ।
  2. मेरी पहनावा-शैली वल्न-रेगेक्स-डिटेक्टर की कोशिश करें जिसमें वेइडमैन के उपकरण और अन्य के लिए सीएलआई है।

अंगूठे का नियम

ईविल रेग्जेस हमेशा संबंधित एनएफए में अस्पष्टता के कारण होते हैं, जिसे आप रीजेक्सपर जैसे उपकरणों के साथ कल्पना कर सकते हैं ।

यहाँ अस्पष्टता के कुछ रूप हैं। अपने regexes में इन का उपयोग न करें।

  1. घोंसले के शिकारियों की तरह (a+)+(उर्फ "स्टार ऊंचाई> 1")। यह घातीय झटका-अप का कारण बन सकता है। सबटैक का safe-regexटूल देखें ।
  2. परिमाणित अतिव्याप्तताएँ जैसे व्यवधान (a|a)+। यह घातीय झटका-अप का कारण बन सकता है।
  3. मात्रात्मक अतिव्याप्ति जैसे आसनों से बचें \d+\d+। यह बहुपद झटका-अप का कारण बन सकता है।

अतिरिक्त संसाधन

मैंने यह पत्र सुपर-लीनियर रेगेक्स पर लिखा था । इसमें अन्य रेगेक्स-संबंधित शोध के संदर्भ शामिल हैं।


4

मैं कहूंगा कि यह उपयोग में रेगेक्स इंजन से संबंधित है। आप हमेशा इन प्रकार के रेगेक्स से बचने में सक्षम नहीं हो सकते हैं, लेकिन यदि आपका रेगेक्स इंजन सही तरीके से बनाया गया है, तो यह कम समस्या है। रेगेक्स इंजन के विषय पर जानकारी के लिए इस ब्लॉग श्रृंखला को देखें ।

लेख के निचले भाग में चेतावनी पर ध्यान दें, उस बैकपैकिंग में एनपी-कम्प्लीट समस्या है। वर्तमान में उन्हें कुशलतापूर्वक संसाधित करने का कोई तरीका नहीं है, और आप उन्हें अपने इनपुट में अस्वीकृत करना चाह सकते हैं।


a*a*backreferences का उपयोग नहीं करता है। अब, रेगेक्स इंजन बैकट्रैकिंग का उपयोग करता है , जो कि, शायद, आपका क्या मतलब है? जिस स्थिति में, सभी आधुनिक इंजन बैकट्रैकिंग का उपयोग करते हैं। आप आसानी से के माध्यम से backtracking को निष्क्रिय कर सकते हैं (?>...), लेकिन यह अधिक बार तब आपकी अभिव्यक्ति के अर्थ को नहीं बदलेगा (और कुछ मामलों में इसे दरकिनार किया जा सकता है)।
JDB को अभी भी मोनिका

@ Cyborgx37 वूप्स! मेरा मतलब बैकट्रैकिंग से था। फिक्स्ड।
स्पेंसर रथबुन

उस स्थिति में, इंजन या तो बैकट्रैकिंग का उपयोग करता है या यह नहीं करता है। वस्तुतः इनपुट को प्रतिबंधित करके बैकट्रैकिंग को प्रतिबंधित करने का कोई तरीका नहीं है।
JDB अभी भी मोनिका

2
@JDB: "सभी आधुनिक इंजन बैकट्रैकिंग का उपयोग करते हैं।" - शायद यह 2013 में सच था, लेकिन अब नहीं
केविन

@ केविन - निश्चित। तुम जीते।
JDB अभी भी मोनिका

3

मुझे नहीं लगता कि आप इस तरह के रीजैक्स को पहचान सकते हैं, कम से कम उन सभी को नहीं या बिना उनकी अभिव्यक्ति को सीमित किए बिना। यदि आप वास्तव में ReDoSs के बारे में परवाह करते हैं, तो मैं उन्हें सैंडबॉक्स करने की कोशिश करूंगा और उनके प्रसंस्करण को टाइमआउट के साथ मारूंगा। यह भी संभव हो सकता है कि वहाँ RegEx कार्यान्वयन हैं जो आपको उनकी अधिकतम सीमा राशि को सीमित करते हैं।


2
मुझे लगता है कि आप प्रश्न को गलत समझ रहे हैं। जैसा कि मैंने इसे पढ़ा, ओपी शाब्दिक रूप से पूछ रहा है कि वह एक दुष्ट रेगेक्स को कैसे पहचान सकता है, न कि वह ऐसा करने के लिए एक कार्यक्रम कैसे लिख सकता है। जैसे, "मैंने इस रेगेक्स को लिखा है, लेकिन मैं यह कैसे बता सकता हूं कि यह बुराई हो सकती है?"
रुख

उह, आप सही हो सकते हैं। मैं तब केवल भयावह बैकट्रैकिंग के बारे में लेख की सिफारिश कर सकता हूं जो @DanielHilgarth पहले से ही टिप्पणियों में जुड़ा हुआ है।
Bergi

2
@ 0x90: क्योंकि मैं उदाहरण के लिए a*या \*"असुरक्षित" नहीं मानता ।
ruakh

1
@ 0x90 a*बिल्कुल भी कमजोर नहीं है। इस बीच, a{0,1000}a{0,1000}एक भयावह रेगेक्स होने की प्रतीक्षा कर रहा है। यहां तक ​​कि a?a?सही परिस्थितियों में बुरा परिणाम हो सकता है।
JDB को अभी भी

2
@ 0x90 - जब आप दो भाव रखते हैं, जहां एक या दूसरे के उपसमूह के समान है, जहां अभिव्यक्ति की लंबाई चर रही है और जहां वे इस तरह तैनात हैं कि कोई एक या एक से अधिक वर्ण दे सकता है, तब भयावह बैकड्रापिंग एक खतरा है। अन्य पीछे के माध्यम से। उदाहरण के लिए, a*b*c*$सुरक्षित है, लेकिन a*b*[ac]*$क्योंकि, खतरनाक है a*संभावित वर्ण छोड़ नहीं रहा हूं करने के लिए [ac]*करता है, तो bअनुपस्थित है और प्रारंभिक मैच में विफल रहता है (उदाहरण के लिए aaaaaaaaaaaccccccccccd)।
JDB अभी भी मोनिका

0

कुछ तरीके हैं जिनके बारे में मैं सोच सकता हूं कि आप उन्हें छोटे परीक्षण इनपुट पर चलाकर या रेगेक्स की संरचना का विश्लेषण करके कुछ सरलीकरण नियमों को लागू कर सकते हैं।

  • (a+)+ केवल निरर्थक ऑपरेटरों को बदलने के लिए कुछ प्रकार के नियम का उपयोग करके कम किया जा सकता है (a+)
  • ([a-zA-Z]+)* नियम के साथ हमारे नए अतिरेक संयोजन के साथ सरलीकरण भी किया जा सकता है ([a-zA-Z]*)

कंप्यूटर प्रासंगिक अक्षर या वर्णों के क्रमबद्ध रूप से उत्पन्न अनुक्रमों के खिलाफ रेगेक्स के छोटे सबएक्सप्रेस को चलाकर परीक्षण चला सकता है, और यह देखते हुए कि वे सभी किस समूह में समाप्त होते हैं। पहले एक के लिए, कंप्यूटर ऐसा है, जो रेगेक्स है। एक चाहता है, तो इसके साथ प्रयास करें 6aaaxaaq। यह तब देखता है कि सभी ए, और केवल पहला समूह एक समूह में समाप्त होता है, और यह निष्कर्ष निकालता है कि कोई भी कितना भी डालता है, यह कोई फर्क नहीं पड़ता, क्योंकि +समूह में सभी हो जाता है। दूसरा एक, जैसे, अरे, रेक्सक्स अक्षरों का एक गुच्छा चाहता है, इसलिए इसे इसके साथ प्रयास करें -fg0uj=, और फिर यह देखता है कि फिर से प्रत्येक समूह में एक गुच्छा है, इसलिए इसे +अंत में छुटकारा मिलता है ।

अब हमें अगले लोगों को संभालने के लिए एक नए नियम की आवश्यकता है: खत्म-अप्रासंगिक-विकल्प नियम।

  • के साथ (a|aa)+, कंप्यूटर इस पर एक नज़र रखता है और जैसा है, हम उस बड़े दूसरे को पसंद करते हैं, लेकिन हम उस पहले का उपयोग अधिक अंतराल में भरने के लिए कर सकते हैं, हमें कई एएएस मिलते हैं जैसा कि हम कर सकते हैं, और देखें कि क्या हम कुछ और प्राप्त कर सकते हैं के बाद हम कर रहे हैं। यह इसे अन्य टेस्ट स्ट्रिंग के खिलाफ चला सकता है, जैसे `eaaa @ a ~ aa। ' यह निर्धारित करने के लिए।

  • आप (a|a?)+कंप्यूटर का एहसास होने से खुद की रक्षा कर सकते हैं कि जिन तारों का मिलान किया a?जाता है, वे हम नहीं ढूंढ रहे हैं, क्योंकि चूंकि यह हमेशा कहीं भी मेल खा सकता है, इसलिए हम तय करते हैं कि हमें चीजें पसंद नहीं हैं (a?)+, और इसे बाहर फेंक दें।

  • हम (.*a){x}यह महसूस करने से बचते हैं कि जिन पात्रों का मिलान किया aगया है, वे पहले ही हड़प गए होंगे .*। फिर हम उस भाग को निकाल देते हैं और निरर्थक क्वांटिफायर को बदलने के लिए एक और नियम का उपयोग करते हैं (.*){x}

इस तरह एक प्रणाली को लागू करना बहुत जटिल होगा, यह एक जटिल समस्या है, और एक जटिल समाधान आवश्यक हो सकता है। आपको अन्य लोगों द्वारा लाई गई तकनीकों का भी उपयोग करना चाहिए, जैसे कि रेग्क्स को निष्पादन संसाधनों की कुछ सीमित मात्रा में ही इसे मारने से पहले अनुमति देता है यदि यह समाप्त नहीं होता है।


1
"जैसा होना", पहचानना "क्या चाहता है", "कोशिश", "अनुमान", "देखना" और ड्राइंग निष्कर्ष ("साकार करना", "निर्धारित करना") गैर-तुच्छ समस्याएं हैं जो कंप्यूटर के लिए एल्गोरिदम को लागू करना कठिन हैं ... और उदाहरणों का परीक्षण करना है। भरोसा करने के लिए कुछ भी नहीं, आपको किसी तरह के साबित करने की आवश्यकता होगी।
बरगी

@Bergi परीक्षण के उदाहरणों से मेरा तात्पर्य यह था कि आप एक पूर्ण रीगेक्स का एक छोटा हिस्सा लेते हैं, और परीक्षण स्ट्रिंग के विरुद्ध यह निर्धारित करते हैं कि यह कैसे व्यवहार करता है। बेशक, आप केवल उन विखंडू का परीक्षण कर रहे हैं जिनकी आपने जांच की है और पहले से ही जानते हैं कि परीक्षण के मामलों में अजीब चीजें नहीं करते हैं।
AJMansfield
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.