2009-03-10 20 views
8

जब कोई उपयोगकर्ता फ़ाइल अपलोड करता है, तो यादृच्छिक रूप से इसे किसी अन्य उपयोगकर्ता के अपलोड द्वारा प्रतिस्थापित किया जाता है, मैंने आखिरकार इस मुद्दे को PHP और tmp फ़ाइल नाम का पुन: उपयोग किया है। क्या इसे ठीक करने का कोई तरीका है? बेहतर यादृच्छिक नाम बनाने का कोई तरीका है? ऐसा लगता है कि समय के साथ गिरावट आ रही है, क्योंकि यादृच्छिक फ़ाइल नाम में बीज कमजोर हो जाता है? http://pastebin.com/m65790440PHP temp फ़ाइल नाम

किसी भी मदद की बहुत सराहना: यह यहाँ दिखा कैसे एक ही tmp फ़ाइल नाम इस्तेमाल किया जाता है और एक अन्य अपलोड द्वारा ओवरराइट है एक लॉग है पीएचपी 5.2.8 और FreeBSD 7.0

पर है। मैं इसे 4 महीने से अधिक समय तक ठीक करने की कोशिश कर रहा हूं और समय के साथ और भी खराब हो गया है। धन्यवाद।

संपादित करें: ध्यान रखें कि यह एक PHP कोड मुद्दा नहीं है, यह किसी भी PHP कोड तक पहुंचने से पहले हो रहा है, $ _FILES ['name'] ['tmp_name'] के माध्यम से प्राप्त फ़ाइल प्राप्त होने पर गलत है और यह पता चला है कि इसे अपलोड प्रोसेसिंग स्क्रिप्ट

+0

यह आपके टीएमपी डीआईआर समस्या या डीआईआर है जिसे आप फ़ाइल कॉपी/स्थानांतरित करते हैं? – Greg

+0

मुझे फ्रीबेस 8 और PHP 5.3 के साथ एक ही समस्या का अनुभव होता है। पुन: पेश करने के लिए मेरे पास एक बहुत ही सरल अपलोड स्क्रिप्ट है। 5 टेस्ट के लिए टक्कर पाने के लिए यहां काफी संभावना है। यह वास्तव में बुरा है। मेरे पास अभी तक कोई विचार नहीं है जहां से शुरू करना है। उपरोक्त वर्णित अनुसार, यह समस्या Google के लिए भी कठिन है। –

उत्तर

-1

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

+0

क्या PHP नाम फ़ाइल अपलोड आने में ओवरराइड करने का कोई तरीका है? फिलहाल php एक 'phpxxxxx' स्कीमा – mrmanman

2

क्या PHP mod_php के रूप में अपाचे के तहत चल रहा है?

फिर आप create a per-process temporary upload directory जिसका नाम अपने php getmypid() शामिल करने की कोशिश कर सकते हैं, ini_set अपने PHP प्रक्रिया 'upload_tmp_dir उस निर्देशिका के लिए। यदि कोई नया php प्रक्रिया प्रत्येक अनुरोध के लिए तैयार की जाती है तो यह काम नहीं करेगा।

+0

का उपयोग करता है क्या PHP नाम फ़ाइल अपलोड करने में ओवरराइड करने का कोई तरीका है? – mrmanman

+0

नहीं, लेकिन आप अस्थायी निर्देशिका को ओवरराइड (रनटाइम पर) करने में सक्षम हो सकते हैं जहां अस्थायी फ़ाइलों को – vladr

0

अपलोड होने के बाद अपनी फ़ाइलों को उपयोगकर्ता डीआईआर में ले जाएं। उन अस्थायी फ़ाइलों को हटा दिया जाना चाहिए।

+0

डंप किया गया है यह सही फ़िक्स है। PHP की अस्थायी अपलोड फ़ाइलों का केवल तभी रहने का मतलब है जहां वे आपकी प्रसंस्करण स्क्रिप्ट को उस स्थान पर ले जाने के लिए लेते हैं जहां वे वास्तव में हैं। – chaos

+0

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

+0

वे स्थानांतरित किए जा रहे हैं। फ़ाइल जो PHP अपलोड प्रोसेसिंग स्क्रिप्ट $ _FILES ['name'] ['tmp_name'] से प्राप्त होती है, – mrmanman

4

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

हर किसी के लिए: पीएचपी उपयोगकर्ता कोड को संसाधित करने से पहले आंतरिक रूप से अपलोड की गई फाइलों को संभालता है। ये नाम $_FILES['file']['tmp_name'] में संग्रहीत हैं (जहां फ़ाइल पर फ़ाइल इनपुट तत्व का 'फ़ाइल' नाम (उद्धृत) नाम है)।

+0

से शुरू होने में गलत है हाँ मुझे विश्वास है कि आप सही हैं, अब मुझे इसे ठीक करने का तरीका पता होना चाहिए = बी – mrmanman

+0

I ' मैं देख रहा हूं कि मुझे Google पर कुछ मिल सकता है, लेकिन मैंने नहीं किया है। क्या समस्या तब भी होती है जब आप एक अलग निर्देशिका में upload_tmp_dir सेट करते हैं? – Powerlord

+0

हाँ ने अभी इसका परीक्षण किया है और समस्या तब भी होती है जब upload_tmp_dir कुछ अलग पर सेट होता है,/var विभाजन (जहां फाइलें अपलोड की जाती हैं) पर सेट "नोटाइम" इस पर असर डालती है? – mrmanman

3

फ्रीबीएसडी 7 के libc कार्यान्वयन में _gettemp पर प्रासंगिक कोड का पीछा करने के बाद, मैं अस्पष्ट हूं कि tmp_name फ़ाइल की सामग्री कैसे अमान्य हो सकती है। (इसका पता लगाने के लिए, आप PHP 5.2.8 की एक प्रति डाउनलोड कर सकते हैं और main/rfc1867.c में पढ़ सकते हैं - main/php_open_temporary_file.c में लाइन 1018 कॉल, लाइन 227 से शुरू होने वाला फ़ंक्शन, जो कि लाइन 97 पर शुरू होने वाले फ़ंक्शन में मुख्य कार्य है, हालांकि, अनिवार्य रूप से सिर्फ आपके सिस्टम पर mkstemp के लिए एक रैपर है, जो लाइन 66 (लिंक) पर FreeBSD libc implementation में पाया जाता है, जो वास्तव में यादृच्छिक फ़ाइल नाम उत्पन्न करने के लिए _gettemp (ऊपर जैसा ही) का उपयोग करता है। हालांकि the manpage for mkstemp बीयूजीएस अनुभाग में उल्लेख करता है कि arc4random() function है पुनर्वित्त नहीं। हो सकता है कि 2 एक साथ अनुरोध महत्वपूर्ण कोड अनुभाग में प्रवेश कर रहे हों और उसी tmp_name लौट रहे हों - मुझे इस बारे में बहुत कुछ पता है कि अपाचे कैसे mod_php या php-cgi के साथ काम करने के लिए काम करता है (हालांकि FastCGI/php का उपयोग करना -सीजीआई काम कर सकता है - मैं इस समय इस पर सफलतापूर्वक टिप्पणी नहीं कर सकता)।

हालांकि, यदि आप फ़ाइल को tmp_name फ़ाइल का अनुभव नहीं कर रहे हैं, तो सबसे आसान समाधान का लक्ष्य है, लेकिन अन्य अपलोड की गई फ़ाइलों के साथ टकरा रहा है (उदाहरण के लिए, यदि tmp_name के फ़ाइल नाम का उपयोग विशिष्टता के आपके एकमात्र स्रोत के रूप में करते हैं संग्रहीत फ़ाइल नाम), birthday paradox के कारण आप टकराव का सामना कर सकते हैं। another question में आप कुछ 5,000,000 फ़ाइलों को स्थानांतरित करने का उल्लेख करते हैं, और still another question में आप एक दिन में 30-40k अपलोड प्राप्त करने का उल्लेख करते हैं। यह मुझे जन्मदिन के विरोधाभास टकराव के लिए एक प्रमुख स्थिति के रूप में हमला करता है। mktemp man page का उल्लेख है कि (यदि PHP के रूप में छः 'एक्सएस' का उपयोग करना है) 56,800,235,584 संभावित फ़ाइल नाम हैं (62 ** 6, या 62 ** एन जहां n = 'एक्स' की संख्या आदि)। हालांकि, यह देखते हुए कि आपके पास 5 मिलियन से अधिक फाइलें हैं, टकराव की संभावना approximately 100% है (एक और ह्युरिस्टिक सुझाव देता है कि आप पहले ही 220 टकराव के कुछ ऑर्डर का अनुभव कर चुके हैं, अगर ((फाइल * (फाइल -1))/2)/(62 ** 6) का मतलब कुछ भी है, जहां फाइल = 5,000,000)। यदि यह समस्या है जिसका आप सामना कर रहे हैं (संभावित, यदि जेनरेट किए गए अपलोड किए गए फ़ाइल नाम पर आगे एन्ट्रॉपी नहीं जोड़ रहा है), तो आप move_uploaded_file($file['tmp_name'], UPLOADS.sha1(mt_rand().$file['tmp_name']).strrchr($file['name'], '.')) जैसे कुछ कोशिश कर सकते हैं - यादृच्छिक फ़ाइल नाम पर अधिक यादृच्छिकता जोड़ने का विचार, टकराव को रोकने। main/php_open_temporary_file.c की लाइन 134 में दो और 'एक्सएस' जोड़ने का एक विकल्प हो सकता है और पुन: संकलित किया जा सकता है।

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