2012-07-30 10 views
10

मैं पाइथन पर आधारित एक वेब सर्वर लिख रहा हूं जो "प्लगइन्स" निष्पादित करने में सक्षम होना चाहिए ताकि कार्यक्षमता को आसानी से बढ़ाया जा सके।पायथन: क्रूट और चेजेल के साथ अविश्वसनीय स्क्रिप्ट/उपप्रोसेसर को सुरक्षित करना?

इसके लिए मैंने कई फ़ोल्डर्स (प्रत्येक प्लगइन के लिए एक) और कई शैल/पायथन स्क्रिप्ट्स के दृष्टिकोण के रूप में विचार किया है, जो विभिन्न घटनाओं के लिए पूर्वनिर्धारित नामों के नाम पर नामित हैं।

एक उदाहरण है on_pdf_uploaded.py फ़ाइल जो सर्वर पर पीडीएफ अपलोड होने पर निष्पादित की जाती है। ऐसा करने के लिए मैं पायथन के सबप्रोसेस उपकरण का उपयोग करूंगा।

सुविधा और सुरक्षा के लिए, यह मुझे यूनिक्स पर्यावरण चर का उपयोग करने के लिए और जानकारी प्रदान करने और प्रक्रिया की कार्यशील निर्देशिका (cwd) सेट करने की अनुमति देगा ताकि वह सही स्थान तक पहुंच सकें ताकि वह अपना स्थान ढूंढ सके।

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

दुर्भाग्य से मुझे इसके बारे में कुछ भी नहीं मिला, और मैं अविश्वसनीय लिपि पर भरोसा नहीं करना चाहता हूं ताकि वह खुद को जेल में डाल सके।

इसके अलावा, मैं मुख्य/कॉलिंग प्रक्रिया को एक क्रोट जेल में नहीं डाल सकता, क्योंकि प्लगइन कोड एक ही समय में कई प्रक्रियाओं में निष्पादित किया जा सकता है जबकि सर्वर अन्य अनुरोधों का उत्तर दे रहा है।

तो यहां सवाल है: मैं बाकी सर्वरों को दोषपूर्ण, अविश्वसनीय कोड से क्षतिग्रस्त होने से बचाने के लिए न्यूनतम विशेषाधिकारों के साथ एक क्रोट जेल में सबप्रोसेस/स्क्रिप्ट कैसे निष्पादित कर सकता हूं?

धन्यवाद!

+0

यह वास्तव में अपने काम है? क्या उन्हें नहीं पता कि वे किस कोड को चला रहे हैं? जो कुछ भी ... क्या इससे मदद मिलती है? [Os.chroot()] (http://docs.python.org/library/os.html#os.chroot)। साथ ही, 'os' uid आदि के साथ गड़बड़ करने के लिए उपहार मिला है तो, एक नई प्रक्रिया बनाने के लिए, (os.fork()?) तो फिर os.setuid os.execle()। – Logan

उत्तर

2

अपनी जेल बनाने के बाद आप अपने पायथन स्रोत से os.chroot पर कॉल करेंगे। लेकिन फिर भी, दुभाषिया द्वारा पहले से खोले गए किसी भी साझा पुस्तकालय या मॉड्यूल फाइलें खुली रहेंगी, और मुझे नहीं पता कि os.close के माध्यम से उन फ़ाइलों को बंद करने के नतीजे क्या होंगे; मैंने कभी कोशिश नहीं की है।

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

अविश्वसनीय कोड में एक स्ट्रिंग के रूप में अविश्वसनीय कोड में पढ़ने के लिए एक विकल्प और exec code in mynamespace जहां mynamespace एक शब्दकोश है जो केवल अविश्वसनीय कोड को बेनकाब करने के लिए प्रतीकों को परिभाषित करता है। यह पायथन वीएम के भीतर एक "जेल" की तरह होगा। import कथन जैसे चीजों की तलाश में आपको पहले स्रोत को पार्स करना पड़ सकता है, जब तक कि निर्मित __import__ फ़ंक्शन को प्रतिस्थापित नहीं किया जाता है (मुझे अनिश्चितता है)।

+0

मैं गतिशील कोड लोडिंग दृष्टिकोण के साथ गया क्योंकि यह डेटा इंटरचेंज और अपवाद हैंडलिंग की सबसे अच्छी लचीलापन प्रदान करता है। – BastiBen

4

शायद ऐसा कुछ?

# main.py 
subprocess.call(["python", "pluginhandler.py", "plugin", env]) 

फिर,

# pluginhandler.py 
os.chroot(chrootpath) 
os.setgid(gid) # Important! Set GID first! See comments for details. 
os.setuid(uid) 
os.execle(programpath, arg1, arg2, ..., env) 
# or another subprocess call 
subprocess.call["python", "plugin", env]) 

संपादित करें: कांटा(), लेकिन मैं वास्तव में समझ में नहीं आया कि यह क्या किया उपयोग करना चाहता था। इसे देखा। नया कोड!

# main.py 
import os,sys 
somevar = someimportantdata 
pid = os.fork() 
if pid: 
    # this is the parent process... do whatever needs to be done as the parent 
else: 
    # we are the child process... lets do that plugin thing! 
    os.setgid(gid) # Important! Set GID first! See comments for details. 
    os.setuid(uid) 
    os.chroot(chrootpath) 
    import untrustworthyplugin 
    untrustworthyplugin.run(somevar) 
    sys.exit(0) 

This उपयोगी था और मैं काफी सिर्फ इतना है कि कोड है, तो प्रशंसा एक सभ्य उदाहरण के लिए है कि पुरुष को चुरा लिया।

+1

यह मेरे मुद्दों को काफी हल करता है। वर्चुअलनव के भीतर psutil की स्थापना और उपयोगकर्ता अनुमतियों के कारण यह बात मुश्किल थी, लेकिन कुछ कोशिश/त्रुटि के बाद मैंने इसे ठीक किया। – coya

+0

@habnabit क्या आप अपने संपादन पर विस्तृत कर सकते हैं? मैं इस बात से अपरिचित हूं कि ऑर्डर क्यों मायने रखता है और मेरा मानना ​​है कि अगर इसका सुरक्षा प्रभाव पड़ता है तो जवाब में इसे स्पष्ट रूप से बुलाया जा सकता है। – Logan

+1

@Logan https://stackoverflow.com/a/11062896 – habnabit

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