सवाल PHP विकल्प 'cgi.fix_pathinfo' वास्तव में Nginx + PHP-FPM के साथ खतरनाक है?


वहाँ किया गया है   बहुत  का  बात कर रहे के सापेक्ष एक सुरक्षा मुद्दे के बारे में cgi.fix_pathinfo PHP विकल्प Nginx (आमतौर पर PHP-FPM, तेज़ CGI) के साथ उपयोग किया जाता है।

नतीजतन, डिफ़ॉल्ट nginx विन्यास फाइल कहने के लिए प्रयोग किया जाता है:

# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

हालांकि, अब, "आधिकारिक" Nginx विकी कहा गया है कि उपरोक्त PHP विकल्प को अक्षम किए बिना PATH_INFO को सही तरीके से संभाला जा सकता है। तो क्या?

प्रशन

  • क्या आप स्पष्ट रूप से समझा सकते हैं कि क्या करता है cgi.fix_pathinfo करना? (आधिकारिक डॉक्टर बस कहते हैं: "PATH_INFO पर अधिक जानकारी के लिए, CGI चश्मा देखें")
  • PHP वास्तव में इनके साथ क्या करेगा PATH_INFO तथा SCRIPT_FILENAME चर?
  • Nginx के साथ क्यों और कैसे खतरनाक हो सकता है? (विस्तृत उदाहरण)
  • क्या इन कार्यक्रमों के हाल के संस्करणों में समस्या अभी भी मौजूद है?
  • अपाचे कमजोर है?

मैं प्रत्येक चरण में इस मुद्दे को समझने की कोशिश कर रहा हूं। उदाहरण के लिए, मुझे समझ में नहीं आता कि php-fpm यूनिक्स सॉकेट का उपयोग क्यों करें से बच सकता है यह समस्या।


40
2017-09-11 17:35


मूल


आप PATH_INFO और PATH_TRANSLATED के बीच अंतर को समझकर अपने स्वयं के प्रश्न का उत्तर दे सकते हैं: blogs.msdn.com/b/david.wang/archive/2005/08/04/... - Giovanni Tirloni


जवाब:


टीएल; डीआर - फिक्स (जिसे आपको भी आवश्यकता नहीं हो सकती है) बहुत सरल है और इस उत्तर के अंत में है।

मैं आपके विशिष्ट प्रश्नों को संबोधित करने की कोशिश करूंगा, लेकिन PATH_INFO के बारे में आपकी गलतफहमी प्रश्नों को स्वयं थोड़ा गलत बनाती है।

  • पहला सवाल होना चाहिए "यह पथ जानकारी व्यवसाय क्या है?"

    • पथ जानकारी एक यूआरआई में लिपि के बाद सामान है (आगे फॉरवर्ड स्लैश से शुरू होना चाहिए, लेकिन क्वेरी तर्क से पहले समाप्त होता है, जो एक से शुरू होता है ?)। के अवलोकन खंड में अंतिम पैराग्राफ सीजीआई के बारे में विकिपीडिया लेख इसे अच्छी तरह से बताता है। नीचे PATH_INFO है "/ यह / आईएस / पथ / जानकारी" है:

      http://example.com/path/to/script.php/THIS/IS/PATH/INFO?query_args=foo

  • आपका अगला प्रश्न यह होना चाहिए था: "PHP कैसे निर्धारित करता है PATH_INFO तथा SCRIPT_FILENAME कर रहे हैं? "

    • PHP के पहले संस्करण बेवकूफ थे और तकनीकी रूप से भी समर्थन नहीं किया था PATH_INFO, तो क्या होना चाहिए था PATH_INFO पर उलझा हुआ था SCRIPT_FILENAME जो, हाँ, कई मामलों में टूट गया है। मेरे पास परीक्षण करने के लिए PHP का पुराना पर्याप्त संस्करण नहीं है, लेकिन मुझे विश्वास है कि यह देखा गया है SCRIPT_FILENAME पूरे शेबैंग के रूप में: उपरोक्त उदाहरण में "/path/to/script.php/THIS/IS/PATH/INFO" (सामान्य रूप से डॉक्रूट के साथ उपसर्ग)।
    • Cgi.fix_pathinfo सक्षम होने के साथ, PHP अब उपर्युक्त उदाहरण के लिए "/ THIS / IS / PATH / INFO" पाता है और इसे इसमें डालता है PATH_INFO तथा SCRIPT_FILENAME केवल उस भाग को प्राप्त करता है जो स्क्रिप्ट को अनुरोध किया जाता है (कोर्स के डॉक्रूट के साथ उपसर्ग)।
    • नोट: जब PHP वास्तव में समर्थन करने के लिए चारों ओर मिल गया PATH_INFO, उन्हें नई सुविधा के लिए कॉन्फ़िगरेशन सेटिंग जोड़नी पड़ती थी ताकि पुराने व्यवहार पर निर्भर स्क्रिप्ट चलाने वाले लोग नए PHP संस्करण चला सकें। यही कारण है कि इसके लिए एक विन्यास स्विच भी है। यह शुरुआत से ("खतरनाक" व्यवहार के साथ) में अंतर्निहित होना चाहिए था।
  • लेकिन PHP कैसे जानता है कि स्क्रिप्ट क्या हिस्सा है और यह पथ जानकारी क्या है? क्या होगा यदि यूआरआई कुछ ऐसा है:

    http://example.com/path/to/script.php/THIS/IS/PATH/INFO.php?q=foo

    • यह कुछ वातावरण में एक जटिल सवाल हो सकता है। PHP में क्या होता है यह है कि यह यूआरआई पथ का पहला भाग पाता है जो सर्वर के डॉक्रूट के तहत कुछ भी नहीं है। इस उदाहरण के लिए, यह देखता है कि आपके सर्वर पर आपके पास "/docroot/path/to/script.php/THIS" नहीं है लेकिन आपके पास निश्चित रूप से "/docroot/path/to/script.php" है, इसलिए अब SCRIPT_FILENAME निर्धारित किया गया है और PATH_INFO बाकी हो जाता है।
    • तो अब खतरे का अच्छा उदाहरण है जो Nginx दस्तावेज़ों में और अंदर अच्छी तरह से विस्तृत है Hrvoje Špoljar का जवाब (आप इस तरह के स्पष्ट उदाहरण के बारे में चिंतित नहीं हो सकते हैं) और भी स्पष्ट हो जाता है: Hrvoje के उदाहरण दिए गए ("http://example.com/foo.jpg/nonexistent.php "), PHP आपके डॉक्रूट" /foo.jpg "पर एक फ़ाइल देखता है लेकिन इसे" /foo.jpg/nonexistent.php "नामक कुछ भी नहीं दिखाई देता है SCRIPT_FILENAME "/foo.jpg" हो जाता है (फिर से, docroot के साथ prefixed) और PATH_INFO "/nonexistent.php" हो जाता है।
  • क्यों और कैसे खतरनाक हो सकता है अब स्पष्ट होना चाहिए:

    • वेब सर्वर वास्तव में गलती नहीं है - यह सिर्फ यूआरआई को PHP में प्रॉक्सी कर रहा है, जो निर्दोष रूप से पाता है कि "foo.jpg" में वास्तव में PHP सामग्री होती है, इसलिए यह इसे निष्पादित करती है (अब आपको पनडुब्ड किया गया है!)। ये है नहीं विशेष रूप से Nginx प्रति से।
  • असली समस्या यह है कि आप बिना किसी प्रतिबंध के अविश्वसनीय सामग्री को कहीं भी अपलोड कर सकते हैं और आप उसी स्थान पर अन्य मनमानी अनुरोधों की अनुमति देते हैं, जो पीएचपी खुशी से निष्पादित होने पर निष्पादित करता है।
  • इस ट्रिकरी का उपयोग करके अनुरोधों को रोकने के लिए Nginx और Apache को बनाया या कॉन्फ़िगर किया जा सकता है, और इसमें ऐसा करने के लिए बहुत सारे उदाहरण हैं, जिनमें शामिल हैं उपयोगकर्ता 2372674 का जवाबयह ब्लॉग लेख समस्या को अच्छी तरह से बताता है, लेकिन इसमें सही समाधान गुम है।

  • हालांकि, सबसे अच्छा समाधान यह सुनिश्चित करना है कि PHP-FPM सही तरीके से कॉन्फ़िगर किया गया है ताकि यह कभी भी फ़ाइल को निष्पादित नहीं करेगा जब तक कि यह ".php" के साथ समाप्त न हो जाए। यह ध्यान देने योग्य है कि PHP-FPM (~ 5.3.9 +?) के हाल के संस्करणों में यह डिफ़ॉल्ट है, इसलिए यह खतरा अब और अधिक समस्या नहीं है।

समाधान

यदि आपके पास PHP-FPM (~ 5.3.9 +?) का हालिया संस्करण है, तो आपको कुछ भी करने की आवश्यकता नहीं है, क्योंकि नीचे सुरक्षित व्यवहार पहले से ही डिफ़ॉल्ट है।

अन्यथा, php-fpm का पता लगाएं www.conf फ़ाइल (शायद /etc/php-fpm.d/www.conf, आपके सिस्टम पर निर्भर करता है)। सुनिश्चित करें कि आपके पास यह है:

security.limit_extensions = .php

दोबारा, यह इन दिनों कई जगहों पर डिफ़ॉल्ट है।

ध्यान दें कि यह किसी हमलावर को ".php" फ़ाइल को वर्डप्रेस अपलोड फ़ोल्डर में अपलोड करने और उसी तकनीक का उपयोग करके निष्पादित करने से नहीं रोकता है। आपको अभी भी अपने अनुप्रयोगों के लिए अच्छी सुरक्षा की आवश्यकता है।


61
2018-06-25 04:09



अच्छा उत्तर! स्पष्टीकरण के लिए: यदि, जैसा कि आप कहते हैं, PHP निर्धारित करता है कि क्या SCRIPT_FILENAME है, वहाँ क्यों है fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; मेरी लाइन में nginx conf? क्या यह मूल्य की खोज करने के लिए PHP के प्रयास को ओवरराइड करता है SCRIPT_FILENAME अपने आप? - Totor
क्या मूल्य प्राप्त करने के लिए कोई कार्य है security.limit_extensions? मैंने कोशिश की phpinfo(), ini_get(security.limit_extensions), तथा ini_get_all() बिना सफलता के। - elbowlobstercowstand


इसके बिना संक्षेप में आप वेब सर्वर पर 'foo.jpg' नामक PHP कोड के साथ फ़ाइल अपलोड कर सकते हैं; फिर इसे पसंद करें http: //domain.tld/foo.jpg/nonexistent.php और वेब सर्वर ढेर गलती से ओह कहेंगे; यह एक PHP है; मुझे इसे संसाधित करने की आवश्यकता है, यह foo.jpg / nonexistent.php को खोजने में विफल रहेगा, इसलिए यह foo.jpg पर वापस आ जाएगा और fp.jpg को php code के रूप में संसाधित करेगा। यह खतरनाक है क्योंकि यह सिस्टम को बहुत आसान घुसपैठ के लिए खोलता है; उदाहरण के लिए छवि अपलोड की अनुमति देने वाला कोई भी वेब एप्लिकेशन बैकडोर अपलोड करने के लिए टूल बन जाता है।

यूनिक्स सॉकेट के साथ php-fpm का उपयोग करने से बचने के लिए; आईएमओ यह समस्या का समाधान नहीं करेगा।


12
2017-09-12 10:04



आप केवल दोहराने वाले लिंक पर पढ़ा जा सकता है। आप असली तंत्र की व्याख्या नहीं करते हैं। आपके उत्तर में अतिरिक्त मूल्य IMHO की आवश्यकता है। - Totor
यह सच हो सकता है, लेकिन आपके शीर्षक का प्रश्न है और उस प्रश्न का उत्तर मेरी प्रतिक्रिया में है। यदि आप इसे स्पष्ट रूप से चाहते हैं; हाँ यह खतरनाक है; बहूत खतरनाक। - Hrvoje Špoljar
1 / मेरा उत्तर इसके शीर्षक तक ही सीमित नहीं है: इसमें एक शरीर है। 2 / user109322 आपको गलत साबित कर दिया है: जो भी मूल्य इस्तेमाल किया जाता है cgi.fix_pathinfo है नहीं खतरनाक, क्योंकि डिफ़ॉल्ट conf php-fpm सुरक्षित है (यह केवल फाइलों को निष्पादित करेगा .php विस्तार)। - Totor


में Nginx विकी सुरक्षा उपाय के रूप में

if (!-f $document_root$fastcgi_script_name) {
    return 404;
}

स्थान ब्लॉक में शामिल है। अन्य ट्यूटोरियल में

try_files $uri =404;

प्रयोग किया जाता है, जो वही करना चाहिए, लेकिन Nginx विकी के अनुसार समस्याएं दे सकता है। इन विकल्पों के साथ, cgi.fix_pathinfo=1 अब कोई समस्या नहीं होनी चाहिए। अधिक जानकारी मिल सकती है यहाँ


1
2018-06-24 13:47