2011-06-28 10 views
32

एसक्यूएलकेमी का उपयोग करते समय एसक्यूएल इंजेक्शन हमलों को कम करने के लिए सबसे अच्छे प्रथाएं क्या हैं?एसक्यूएलकेकी + एसक्यूएल इंजेक्शन

+24

SQLAlchemy * का उपयोग करना * सबसे अच्छा अभ्यास है। :-) –

उत्तर

31

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

[http://www.rmunn.com/sqlalchemy-tutorial/tutorial.html प्रति]

+16

उत्तर कहता है कि उद्धरण "दस्तावेज" से आता है, जब ऐसा नहीं होता है: ऐसा लगता है [यह एक ट्यूटोरियल] (http://www.rmunn.com/sqlalchemy-tutorial/tutorial.html) SQLAlchemy से जुड़ा नहीं है। दूसरा, उद्धरण SQLAlchemy एपीआई के हिस्से के संदर्भ में है जो बचने से निपटने वाले उदाहरण का उपयोग करके बचने से सही तरीके से बच जाएगा। हालांकि, आप अभी भी 'execute() 'या अन्य शाब्दिक डेटा का उपयोग कर सकते हैं जो SQLAlchemy से बच नहीं पाएगा। हां, ज्यादातर मामलों में SQLAlchemy स्वतः से बच जाएगा, लेकिन यदि आप अक्षर या कच्चे एसक्यूएल का उपयोग कर रहे हैं, तो भी आप अपने आप को पैर में शूट कर सकते हैं। –

51

tldr: जितना संभव हो उतना कच्चे एसक्यूएल से बचें।

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

session.query(MyClass).filter("foo={}".format(getArgs['val']))

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

http://domain.com/?val=2%20or%201%20=%201

+4

"जब तक आप जानबूझकर SQLAlchemy के उद्धरण तंत्र को बाईपास नहीं करते ..."हाँ कच्चे एसक्यूएल में प्रवेश करना जानबूझकर उस उद्धरण तंत्र को छोड़कर है। इसलिए नहीं, उपर्युक्त उत्तर गलत नहीं है। – Johnston

+12

मैं असहमत हूं। आप फ़िल्टर विधि में कच्चे एसक्यूएल को पास कर सकते हैं, स्क्लेक्लेमी का हिस्सा है, कुछ अंत में हैक नहीं ... तो इसके बारे में कुछ पता होना चाहिए। – Mike

+2

यदि मुझे फ़िल्टर के लिए उपयोगकर्ता इनपुट लेना है, तो यह सुनिश्चित करने का सही तरीका क्या है कि उपयोगकर्ता टेबल या किसी अन्य अप्रत्याशित व्यवहार को छोड़ने के लिए कच्चे SQL में प्रवेश नहीं कर रहा है? –

3

@Tendrid answer में जोड़ने के लिए। मैंने चुपचाप दृष्टिकोण का उपयोग करके थोड़ी सी जांच की। filter विधि में *criterion है इसके तर्क के रूप में, कई अन्य ORM क्वेरी विधियों के समान तर्क है।

filter विधि *criterion तर्क _literal_as_text, जो स्ट्रिंग के मामले में में पारित कर दिया समाप्त होता है के मामले में - के निशान के रूप में सुरक्षित एसक्यूएल (कृपया मुझे ठीक कर लें मैं गलत हूँ)। इसलिए यह असुरक्षित बनाता है।

यहाँ *criterion तर्क के साथ ORM Query class विधि जांच का परिणाम है:

filter - uses _literal_as_text (NOT SAFE) 
having - uses _literal_as_text (NOT SAFE) 

distinct - uses _literal_as_label_reference (NOT SAFE) 
group_by - uses _literal_as_label_reference (NOT SAFE) 
order_by - uses _literal_as_label_reference (NOT SAFE) 

join  - uses model attributes to resolve relation (SAFE) 

संभव विधि missuses के उदाहरण (यह आसान रखने के लिए, स्ट्रिंग स्वरूपण को छोड़ दिया है):

db.session.query(User.login).group_by('login').having('count(id) > 4; select name from roles').all() 
db.session.query(User.login).distinct('name) name from roles /*').order_by('*/').all() 
db.session.query(User.login).order_by('users_login; select name from roles').all() 
db.session.query(User.login).group_by('login union select name from roles').all() 

नोट कि स्ट्रिंग शाब्दिक पारित होने पर ये विधियां केवल असुरक्षित हैं।

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