2012-05-09 10 views
5

पृष्ठभूमि:से बचने के लिए एसक्यूएल स्ट्रिंग्स जावा में

मैं वर्तमान में एक एंटरप्राइज़ सीएमएस डेटाबेस (व्यापार वस्तुओं) के लिए एक जावा सामने के छोर को विकसित कर रहा हूँ। फिलहाल, मैं एक सुविधा का निर्माण कर रहा हूं ताकि उपयोगकर्ता को कस्टम डेटाबेस क्वेरी बनाने की अनुमति मिल सके। मैंने यह सुनिश्चित करने के लिए पहले से ही उपायों को कार्यान्वित कर दिया है कि उपयोगकर्ता केवल उपलब्ध कॉलम और ऑपरेटरों के उप-समूह का उपयोग कर चुनने में सक्षम है जिसे उपयोगकर्ता पहुंच के लिए अनुमोदित किया गया है (उदाहरण के लिए SI_EMAIL_ADDRESS का चयन किया जा सकता है जबकि SI_CUID जैसे अधिक शक्तिशाली फ़ील्ड नहीं हो सकते हैं)। अभी तक चीजें तैराकी पर चल रही हैं, लेकिन अब संभावित एसक्यूएल इंजेक्शन हमलों के खिलाफ इस सुविधा को सुरक्षित करने का समय है।

प्रश्न:

मैं उपयोगकर्ता इनपुट तार से बचने के लिए एक विधि के लिए देख रहा हूँ। मैंने पहले से ही पेपरडेस्टेटमेंट देखा है, हालांकि मुझे डेटाबेस तक पहुंचने के लिए तीसरे पक्ष के एपीआई का उपयोग करने के लिए मजबूर होना पड़ता है। ये एपीआई मेरे लिए अपरिवर्तनीय हैं और सीधे डेटाबेस पहुंच प्रश्न से बाहर है। अलग-अलग विधियां चलने वाले प्रश्नों का प्रतिनिधित्व करने वाले तारों को लेती हैं, इस प्रकार प्रीपेडस्टेटमेंट को अमान्य कर दिया जाता है (जो, मेरे ज्ञान के लिए, सीधे डेटाबेस कनेक्शन के विरुद्ध चलाना चाहिए)।

मैंने String.replace() का उपयोग करने पर विचार किया है, लेकिन यदि संभव हो तो मैं पहिया को फिर से शुरू नहीं करना चाहता हूं। इसके अलावा, मैं सुरक्षा विशेषज्ञों से बहुत रोना हूं जो पेपरडेस्टेटमेंट विकसित करते हैं।

मैंने कुछ प्रकार की toString() विधि खोजने की उम्मीद करते हुए, पेपरडेस्टेटमेंट के लिए जावा एपीआई संदर्भ को भी देखा था। हां, मैं इस तरह के कुछ भी खोजने में असमर्थ रहा हूं।

किसी भी मदद की बहुत सराहना की जाती है। पहले ही, आपका बहुत धन्यवाद।

संदर्भ:

Java - escape string to prevent SQL injection

Java equivalent for PHP's mysql_real_escape_string()

उत्तर

2

बेशक यह तैयार किए गए स्तर का उपयोग करने के लिए आसान और अधिक सुरक्षित होगा।

ANSI SQL शुरू करते हैं और एक भी बोली के साथ समाप्त करने के लिए एक स्ट्रिंग शाब्दिक आवश्यकता है, और एक भी बोली के लिए ही भागने तंत्र दो एकल उद्धरण चिह्नों का उपयोग करने के लिए है:

'Joe''s Caffee' 

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

MySQL के लिए, मैं MySQLUtils का उपयोग करने का सुझाव देता हूं। यदि आप MySQL का उपयोग नहीं करते हैं, तो आपको यह जांचने की आवश्यकता है कि उपयोग करने के लिए सटीक भागने के तंत्र क्या हैं।

2

तुम अब भी एक तैयार बयान का इस्तेमाल किया करने में सक्षम हो सकता है। यह पोस्ट देखें: get query from java sql preparedstatement। साथ ही, उस पोस्ट के आधार पर, आप इसे संभालने के लिए Log4JDBC का उपयोग करने में सक्षम हो सकते हैं।

इनमें से कोई भी विकल्प आपको एसक्यूएल इंजेक्शन को रोकने के लिए तारों से बचने के बारे में चिंता करने की आवश्यकता से रोकना चाहिए, क्योंकि तैयार कथन आपके लिए यह करता है।

+0

तुम्हारा की पहली कड़ी पराक्रमी दिलचस्प है कि: यहाँ मेरी नमूना कोड है। मैं अंतर्निहित रूप से परिभाषित स्ट्रिंग() विधि के संभावित अपरिभाषित व्यवहार से चिंतित हूं। एंटरप्राइज़ आर्किटेक्ट्स ने यह सुनिश्चित करने के लिए प्रभावशाली प्रयास किए हैं कि डेटाबेस स्वयं छिपा हुआ है (जैसा कि उन्हें चाहिए)। मुझे यह भी नहीं पता कि डीबीएमएस क्या चल रहा है या भविष्य में इसे बदल दिया जाएगा। – phobos51594

+0

वास्तव में, इसके बारे में सोचने के लिए आओ, यह तैयार किए गए स्तर की तरह दिखता नहीं है यहां तक ​​कि सार्वजनिक रूप से सुलभ कन्स्ट्रक्टर भी है। चूंकि मेरे पास जेडीबीसी कनेक्शन ऑब्जेक्ट नहीं है, इसलिए मुझे यकीन नहीं है कि मैं कैसे तैयार किए गए स्टेमेंट ऑब्जेक्ट को शुरू करने के लिए भी प्राप्त कर सकता हूं। हम्म। – phobos51594

+0

हाँ, मैं देख सकता हूं कि यह कैसे एक कन्डर्रम होगा। मैंने Log4JDBC का उपयोग नहीं किया है, लेकिन ऐसा लगता है कि यह तैयार कथन के आधार पर आपके लिए SQL उत्पन्न करने में सक्षम हो सकता है। – ametren

0

हालांकि, जावा में PHP के mysql_real_escape_string() को संभालने का कोई मानक तरीका नहीं है, मैंने किसी भी अपवाद से बचने के लिए आवश्यक हर पहलू को संभालने के लिए सभी विधि को बदलने के लिए किया था।

public void saveExtractedText(String group,String content) { try { content = content.replaceAll("\", "\\") .replaceAll("\n","\n") .replaceAll("\r", "\r") .replaceAll("\t", "\t") .replaceAll("\00", "\0") .replaceAll("'", "\'") .replaceAll("\"", "\\"");

state.execute("insert into extractiontext(extractedtext,extractedgroup) values('"+content+"','"+group+"')"); 
} catch (Exception e) { 
    e.printStackTrace(); 

} 

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