url के अंदर डबल एस्केप अनुक्रम: अनुरोध फ़िल्टरिंग मॉड्यूल एक अनुरोध से इनकार करने के लिए कॉन्फ़िगर किया गया है जिसमें डबल एस्केप अनुक्रम शामिल है


86

मेरे ASP.NET MVC एप्लिकेशन पर, मैं नीचे जैसा URL लागू करने का प्रयास कर रहा हूं:

/ उत्पाद / टैग / + परिवारों के लिए

जब मैं अपने एप्लिकेशन को डिफ़ॉल्ट कॉन्फ़िगरेशन के साथ चलाने का प्रयास करता हूं, तो मुझे यह संदेश 404.11 रिस्पांस कोड के साथ मिल रहा है:

HTTP एरर 404.11 - नहीं मिला

अनुरोध फ़िल्टरिंग मॉड्यूल एक अनुरोध से इनकार करने के लिए कॉन्फ़िगर किया गया है जिसमें डबल एस्केप अनुक्रम शामिल है।

मैं नीचे दिए गए कोड को अपने web.config के अंदर लागू करके इस त्रुटि को प्राप्त कर सकता हूं:

  <system.webServer>
    <security>
      <requestFiltering allowDoubleEscaping="true" />
    </security>
  </system.webServer>

इसलिए, अब मुझे कोई नहीं मिल रहा है 404.11

जो मैं सोच रहा हूं वह यह है कि इस कार्यान्वयन के साथ मैं किस तरह के सुरक्षा छेद खोल रहा हूं।

BTW, मेरा आवेदन के तहत .Net Framework 4.0और चल रहा है IIS 7.5


क्या इसके /product/tags/for%20familiesबजाय वांछित संसाधन तक पहुंचना संभव है ? फिर आपके पास रिक्त स्थान वाले आईडी के लिए वर्कअराउंड है। या मैं यहाँ पूरी तरह से बंद हूँ?
एंडर्स टॉर्बलाड

@atornblad थोड़ा सा मुझे लगता है। मेरा प्रश्न: मैं जो सोच रहा हूं वह यह है कि इस कार्यान्वयन के साथ मैं किस तरह के सुरक्षा छेद खोल रहा हूं।
तुगलक

5
IIS "+" वर्ण पर फेंक रहा है, जो Microsoft का डिफ़ॉल्ट व्यवहार है।
टॉड शेल्टन

जवाबों:


57

आपके द्वारा खोले जा सकने वाले सुरक्षा छेद को कोड इंजेक्शन - HTML इंजेक्शन, जावास्क्रिप्ट इंजेक्शन या SQL इंजेक्शन के साथ करना होगा।

डिफ़ॉल्ट सेटिंग्स आम इंजेक्शन रणनीतियों को काम करने की अनुमति नहीं देकर आपको अर्ध-कुशलता से हमलों से बचाती हैं। जितनी अधिक डिफ़ॉल्ट सुरक्षा आप हटाते हैं, उतना ही आपको यह सोचना होगा कि आप URL के माध्यम से प्रदान किए गए इनपुट के साथ क्या करते हैं, GET अनुरोध querystrings, POST अनुरोध डेटा, HTTP हेडर और इतने पर ...

उदाहरण के लिए, यदि आप idअपनी क्रिया पद्धति के पैरामीटर के आधार पर गतिशील SQL प्रश्नों का निर्माण कर रहे हैं, तो इस तरह:

public ActionResult Tags(string id)
{
    var sql = "SELECT * FROM Tags Where tagName = '" + id + "'";
    // DO STUFF...
}

((जो एक अच्छा विचार नहीं है), डिफ़ॉल्ट सुरक्षा, .NET फ्रेमवर्क द्वारा डाल दिया जाता है, इस URL का अनुरोध करने वाले उपयोगकर्ता की तरह कुछ और खतरनाक परिदृश्यों को रोक सकता है:

/product/tags/1%27;drop%20table%20Tags;%20--

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

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


6

सुरक्षा जोखिम

सेटिंग allowDoubleEscapingकेवल pathसीएस (सीएसआई-यूरी-स्टेम) पर लागू होती है और इसे ओडब्ल्यूएएसपी डबल एन्कोडिंग द्वारा सबसे अच्छा समझाया गया है । इस तकनीक का उपयोग URL द्वारा सुरक्षा नियंत्रण प्राप्त करने के लिए किया जाता है। उदाहरण के रूप में अपने URL का उपयोग करना:

/product/tags/for+families --> /product/tags/for%2Bfamilies --> /product/tags/for%252Bfamilies

मान लीजिए कि विशेष रूप से सुरक्षा नियंत्रण हैं /product/tags/for+families। एक अनुरोध आता है /product/tags/for%252Bfamiliesजिसके लिए वही संसाधन है जो उपरोक्त सुरक्षा नियंत्रणों द्वारा अनियंत्रित है। मैंने सुरक्षा नियंत्रण के सामान्यीकृत शब्द का उपयोग किया क्योंकि वे कुछ भी हो सकते हैं जैसे कि एक प्रमाणित उपयोगकर्ता की आवश्यकता, SQLi के लिए जाँच आदि।

IIS ब्लॉक क्यों करता है?

धन चिह्न (+) RFC2396 प्रति एक आरक्षित वर्ण है :

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

  reserved    = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
                "$" | ","

वेड हिल्मो का एक उत्कृष्ट पोस्ट है जिसका शीर्षक है कि कैसे यूआरएल में वर्णों को IIS ब्लॉक करता है । बहुत सारी जानकारी और पृष्ठभूमि प्रदान की गई है। प्लस साइन के लिए विशेष रूप से भाग इस प्रकार है:

तो DDDEEश्योरिंग / VerifyNormalization बहुत सीधा लगता है। मैंने यह क्यों कहा कि यह भ्रम का कारण बनता है? मुद्दा तब है जब URL में '+' वर्ण दिखाई देता है। '+' वर्ण बचता नहीं दिखता, क्योंकि इसमें '%' शामिल नहीं होता है। इसके अलावा, RFC 2396 इसे एक आरक्षित चरित्र के रूप में नोट करता है, जो URL में तब शामिल किया जा सकता है जब वह बच गए फॉर्म (% 2b) में हो। लेकिन झूठा करने के लिए डिफ़ॉल्ट मान के लिए सेट किए गए अनुमति के साथ, हम इसे बच गए रूप में भी ब्लॉक कर देंगे। इसका कारण ऐतिहासिक है: रास्ता HTTP के शुरुआती दिनों में, एक '+' वर्ण को अंतरिक्ष वर्ण के लिए शॉर्टहैंड माना जाता था। कुछ canonicalizers, जब एक URL दिया जाता है जिसमें '+' होता है, इसे एक स्थान पर परिवर्तित कर देगा। इस कारण से, हम एक URL में '+' को गैर-विहित मानते हैं। मुझे इस '+' उपचार का आह्वान करने वाले RFC के लिए कोई संदर्भ नहीं मिला,

अपने स्वयं के अनुभव से मुझे पता है कि जब आईआईएस लॉग अनुरोध करता है तो एक प्लस चिह्न के साथ प्रतिस्थापित किया जाता है। नाम में प्लस साइन होने पर पार्सिंग लॉग्स के कारण भ्रम हो सकता है।

समाधान

इसे ठीक करने के तीन तरीके हैं और दो तरीके अभी भी प्लस साइन का उपयोग करते हैं।

  1. allowDoubleEscaping=true- यह आपकी पूरी वेबसाइट / एप्लिकेशन के लिए डबल भागने की अनुमति देगा। सामग्री के आधार पर, यह कम से कम कहने के लिए अवांछनीय हो सकता है। निम्न कमांड सेट करेगा allowDoubleEscaping=true

    appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /allowDoubleEscaping:True
    
  2. alwaysAllowedUrls- अनुरोध फ़िल्टरिंग एक श्वेतसूची दृष्टिकोण प्रदान करता है। उस URL पथ को हमेशा जोड़े जाने से, अनुरोध को किसी अन्य अनुरोध फ़िल्टरिंग सेटिंग द्वारा चेक नहीं किया जाएगा और IIS अनुरोध पाइपलाइन में जारी रहेगा। यहाँ चिंता का विषय यह है कि अनुरोध फ़िल्टरिंग अनुरोध के लिए जाँच नहीं करेगा:

    • अनुरोध सीमाएँ: maxContentLength, maxUrl, maxQueryString
    • क्रिया
    • क्वेरी - क्वेरी स्ट्रिंग मापदंडों की जाँच नहीं की जाएगी
    • डबल भागने
    • उच्च बिट वर्ण
    • फ़िल्टरिंग नियमों का अनुरोध करें
    • अनुरोध हैडर सीमा

    निम्न आदेश जोड़ देगा /product/tags/for+familiesकरने के लिए alwaysAllowedUrlsडिफ़ॉल्ट वेब साइट पर।

    appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"alwaysAllowedUrls.[url='/product/tags/for+families']"
    
  3. नाम बदलें - हाँ, बस फ़ाइल / फ़ोल्डर / नियंत्रक / आदि का नाम बदलें। अगर संभव हो तो। यह सबसे आसान उपाय है।


: आईआईएस एक्सप्रेस के साथ विकास के दौरान allowDoubleEscaping करने के लिए यहाँ मैं क्या किया है stackoverflow.com/q/56463044/381082
DeveloperDan

3

मैंने इसके लिए एक काम किया है। इसलिए जब आप (IIS) के लिए url के अंदर एनक्रिप्टेड स्ट्रिंग रखना चाहते हैं तो आपको उसे गंदे से साफ़ करना होगा: {";", "/", "?", ":", "@", "&", " = "," + "," $ ",", "}; और जब आप इसे डिक्रिप्ट करना चाहते हैं और इसे फिर से उपयोग करना चाहते हैं, तो आपको इसे डीक्रिप्ट करने से पहले इसे फिर से गंदा करना होगा (वांछित परिणाम प्राप्त करने के लिए)।

यहाँ मेरा कोड है, मुझे आशा है कि यह किसी की मदद करता है:

 public static string cleanUpEncription(string encriptedstring)
        {
            string[] dirtyCharacters = { ";", "/", "?", ":", "@", "&", "=", "+", "$", "," };
            string[] cleanCharacters = { "p2n3t4G5l6m","s1l2a3s4h","q1e2st3i4o5n" ,"T22p14nt2s", "a9t" , "a2n3nd","e1q2ua88l","p22l33u1ws","d0l1ar5","c0m8a1a"};

            foreach (string dirtyCharacter in dirtyCharacters)
            {
                encriptedstring=encriptedstring.Replace(dirtyCharacter, cleanCharacters[Array.IndexOf(dirtyCharacters, dirtyCharacter)]);
            }
            return encriptedstring;
        }

        public static string MakeItDirtyAgain(string encriptedString)
        {
            string[] dirtyCharacters = { ";", "/", "?", ":", "@", "&", "=", "+", "$", "," };
            string[] cleanCharacters = { "p2n3t4G5l6m", "s1l2a3s4h", "q1e2st3i4o5n", "T22p14nt2s", "a9t", "a2n3nd", "e1q2ua88l", "p22l33u1ws", "d0l1ar5", "c0m8a1a" };
            foreach (string symbol in cleanCharacters)
            {
                encriptedString = encriptedString.Replace(symbol, dirtyCharacters[Array.IndexOf(cleanCharacters,symbol)]);
            }
            return encriptedString;
        }

PntGlm क्या है?
स्टुपरयूजर

@StuperUser केवल यादृच्छिक वर्ण
मार्क डिबेह

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

base64 के साथ समस्या है / एक base64 चरित्र है और मार्गों को तोड़ सकता है
Garr Godfrey

1

इसलिए मैं इसमें भाग गया जब मैं एक एमवीसी ऐप से एपीआई कॉल कर रहा था। सुरक्षा छेद खोलने के बजाय, मैंने अपना पथ संशोधित किया।

सबसे पहले, मैं इस सेटिंग को अक्षम नहीं करने की सलाह देता हूं। एप्लिकेशन / संसाधन के डिज़ाइन को संशोधित करना अधिक उपयुक्त है (उदाहरण के लिए पथ को एन्कोड करें, डेटा को हेडर या बॉडी में पास करें)।

हालाँकि यह एक पुरानी पोस्ट है, मैंने सोचा कि मैं साझा करूँगा कि आप इस त्रुटि को कैसे हल कर सकते हैं यदि आप एक कॉल से एपीआई तक HttpUtility.UrlPathEncode पद्धति का उपयोग करके System.Web में प्राप्त कर रहे हैं ।

मैं का उपयोग RestSharp तो मेरे उदाहरण RestRequest उपयोग कर रहा है कॉल बाहर बनाने के लिए,:

var tags = new[] { "for", "family" };
var apiRequest = new RestRequest($"product/tags/{HttpUtility.UrlPathEncode(string.Join("+", tags))}");

यह इसके बराबर एक पथ का निर्माण करता है:

/ उत्पाद / टैग /% 2Bfamilies के लिए

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

~ चीयर्स


0

एन्क्रिप्ट की गई स्ट्रिंग को अलग करें:

return HttpServerUtility.UrlTokenEncode(Encoding.UTF8.GetBytes("string"));

एन्क्रिप्ट किए गए स्ट्रिंग को अलग कर दें:

string x = Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(id));
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.