2010-08-03 14 views
10

उपयोगकर्ता द्वारा सर्वर पर एक छवि अपलोड करने के बाद, क्या हमें $_FILES['filename']['name'] को स्वच्छ करना चाहिए?

मैं फ़ाइल आकार/फ़ाइल प्रकार आदि की जांच करता हूं लेकिन मैं अन्य चीजों की जांच नहीं करता हूं। क्या कोई संभावित सुरक्षा छेद है?

आप

+0

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

उत्तर

6

बिल्कुल! जैसा कि @ बॉब ने पहले से ही उल्लेख किया है कि सामान्य फ़ाइल नामों को ओवरराइट करने के लिए यह बहुत आसान है।

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

function Upload($source, $destination, $chmod = null) 
{ 
    $result = array(); 
    $destination = self::Path($destination); 

    if ((is_dir($destination) === true) && (array_key_exists($source, $_FILES) === true)) 
    { 
     if (count($_FILES[$source], COUNT_RECURSIVE) == 5) 
     { 
      foreach ($_FILES[$source] as $key => $value) 
      { 
       $_FILES[$source][$key] = array($value); 
      } 
     } 

     foreach (array_map('basename', $_FILES[$source]['name']) as $key => $value) 
     { 
      $result[$value] = false; 

      if ($_FILES[$source]['error'][$key] == UPLOAD_ERR_OK) 
      { 
       $file = ph()->Text->Slug($value, '_', '.'); 

       if (file_exists($destination . $file) === true) 
       { 
        $file = substr_replace($file, '_' . md5_file($_FILES[$source]['tmp_name'][$key]), strrpos($value, '.'), 0); 
       } 

       if (move_uploaded_file($_FILES[$source]['tmp_name'][$key], $destination . $file) === true) 
       { 
        if (self::Chmod($destination . $file, $chmod) === true) 
        { 
         $result[$value] = $destination . $file; 
        } 
       } 
      } 
     } 
    } 

    return $result; 
} 

महत्वपूर्ण हिस्से हैं:

  1. array_map('basename', ...), इस सुनिश्चित करें कि फ़ाइल किसी भी संबंधित पथ शामिल नहीं है बनाता है

    यहाँ Upload() विधि मैं phunction PHP framework के लिए लिखा है।

  2. ph()->Text->Slug(), इस यकीन है कि केवल .0-9a-zA-Z फ़ाइल नाम में अनुमति दी जाती है बनाता है, अन्य सभी वर्ण अंडरस्कोर (_)
  3. md5_file() ने ले ली है, इस iff फ़ाइल नाम में जोड़ा जाता है एक ही नाम के साथ एक और फ़ाइल पहले से ही मौजूद है

मैं उपयोगकर्ता की आपूर्ति नाम का उपयोग करने के बाद से खोज इंजन का उपयोग बेहतर परिणाम देने के लिए कर सकते हैं, लेकिन अगर जो आपके लिए महत्वपूर्ण नहीं है एक साधारण microtime(true) या md5_file() एक सा बातें आसान बनाने में कर सकता है।

आशा है कि इससे मदद मिलती है! =)

+3

मुझे उम्मीद है कि अगर (is_dir ($ गंतव्य) * array_key_exists ($ स्रोत, $ _FILES) == 1) 'कुछ प्रकार का मजाक है ...:-P – deceze

+0

बूलियन गुणा एक वैध विधि है, लेकिन मैं यह सोचने के लिए चिल्लाता हूं कि क्या होगा यदि यह वीबी था, जहां गलत है -1। इस तरह की चीज को किसी भी तरह से देखने के लिए डरावना। –

+1

@Marc "वैध विधि" जैसा कि "यह काम करने के लिए होता है"? मुझे केवल '&&' पर कोई लाभ नहीं होने पर कोड obfuscation का मामूली मामला दिखाई देता है। – deceze

1

आप भी नकली नाम के लिए जांच करने की आवश्यकता धन्यवाद। एकाधिक लोगों के लिए 'mycat.jpg' नामक एक छवि अपलोड करना बहुत आसान है, जो एक ही फ़ोल्डर में अपलोड होने पर पहले से अपलोड की गई फ़ाइल को उसी नाम से ओवरराइट करेगा। आप इसे फ़ाइल नाम में एक अद्वितीय आईडी डालकर कर सकते हैं (जैसा कि प्रिक्स सुझाव देता है)। यह भी सत्यापित करें कि फ़ाइल प्रकार केवल छवि एक्सटेंशन के साथ समाप्त नहीं होता है बल्कि यह एक वास्तविक छवि भी है; आप नहीं चाहते हैं कि आपका सर्वर यादृच्छिक फ़ाइलों के लिए एक अंधेरे मेजबान के रूप में कार्य कर रहा हो।

4

फ़ाइल नाम एक मनमाना उपयोगकर्ता आपूर्ति स्ट्रिंग है। एक सामान्य नियम के रूप में, मनमाने ढंग से उपयोगकर्ता द्वारा प्रदत्त मानों पर भरोसा न करें।

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

संबंधित मुद्दे