7

से नीचे रोकता है नीचे दिया गया कोड SAMATE Reference Dataset से है। मैंने इसे एक स्थिर विश्लेषण उपकरण का परीक्षण करने के लिए उपयोग किया। जैसा कि आप देख सकते हैं कि कोड को सैनिटाइजेशन विधि के साथ-साथ तैयार कथन का उपयोग करके SQL-इंजेक्शन को रोकना चाहिए।क्या तैयार कथन SQL-इंजेक्शन को

चूंकि एससीए उपकरण कस्टम सैंटिज़ेशन विधियों को नहीं जानते हैं, इसलिए यह पता नहीं लगाएगा कि इंजेक्शन को रोकने के लिए allowed विधि का उपयोग किया जाता है।

public class SQLInjection_good_089 extends HttpServlet 
{ 
    private static final long serialVersionUID = 1L; 

    public SQLInjection_good_089() 
    { 
     super(); 
    } 

    // Table of allowed names to use 
    final String allowed_names[] = { "Mickael", "Mary", 
      "Peter", "Laura", "John"}; 

    // Function to check if the current name takes part of the allowed ones 
    public boolean allowed(String in) 
    { 
     boolean bool = false; 

     for(int i = 0; i < 5; i++) 
     { 
      if(in.equals(allowed_names[i])) 
      { 
       // the current name is allowed to use 
       bool = true; 
       break; 
      } 
     } 
     return bool; 
    } 

    // Method which will be called to handle HTTP GET requests 
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
     throws ServletException, IOException 
    { 
     // Initialize the output stream 
     resp.setContentType("text/html"); 
     ServletOutputStream out = resp.getOutputStream(); 
     out.println("<HTML><BODY><blockquote><pre>"); 
     Connection conn = null; 

     // Get the parameter "name" from the data provided by the user 
     String name = req.getParameter("name"); 

     if ((name != null) && (allowed(name) == true)) 
     { 
      try 
      { 
       // Set the context factory to use to create the initial context 
       System.setProperty (Context.INITIAL_CONTEXT_FACTORY, "your.ContextFactory"); 

       // Create the initial context and use it to lookup the data source 
       InitialContext ic = new InitialContext(); 
       DataSource dataSrc = (DataSource) ic.lookup ("java:comp/env/jdbc:/mydb"); 

       // Create a connection to the SQL database from the data source 
       conn = dataSrc.getConnection(); 

       // Send a SQL request to the database 
       PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE firstname LIKE ?"); 
       // replace the first parameter by name 
       ps.setString(1, name); 
       ps.executeQuery(); 
      } 
      catch(NamingException e) 
      { 
       out.println("Naming exception"); 
      } 
      catch(SQLException e) 
      { 
       out.println("SQL exception"); 
      } 
      finally 
      { 
       try 
       { 
        if (conn != null) 
         conn.close(); 
       } 
       catch (SQLException se) 
       { 
        out.println("SQL Exception"); 
       } 
      } 
     } 
     else 
      return; 

     out.println("</pre></blockquote></body></html>"); 
    } 

    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException 
    { 
    } 
} 

फिर भी मुझे लगता है कि तैयार कथन के उपयोग को इंजेक्शन को वैसे भी रोकना चाहिए। क्या मैं गलत हूँ?

उत्तर

3

आप सही हैं। prepared statement 'अवैध' एसक्यूएल इनपुट का ख्याल रखेगा।

allowed(...) फ़ंक्शन व्यवसाय नियमों के संदर्भ में उपयोगकर्ता इनपुट सत्यापन की तरह है और एसक्यूएल इंजेक्शन को रोकने के लिए नहीं है।

+0

असल में यह मेरा एक गड़बड़ था। मैंने गलती से गलत परियोजना के परिणामों में देखा। कोई बात नहीं। धन्यवाद – er4z0r

1

बस तैयार बयान एसक्यूएल इंजेक्शन को रोकने के लिए पर्याप्त होना चाहिए ...

हालांकि, अगर आप 'बाहर' पैरामीटर के लिए उपयोगकर्ता संदेश लिखने का इरादा (जैसे out.printf("Invalid username %s", name) के रूप में), जावास्क्रिप्ट इंजेक्शन के लिए बाहर देखते हैं। मैं अपना नाम <script>alert('hi')</script>

1

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

3

हां यहां तैयार कथन एसक्यूएल इंजेक्शन को रोक देगा। ऐसा इसलिए है क्योंकि आप प्लेसहोल्डर (?) क्वेरी में उपयोग कर रहे हैं। यह प्लेसहोल्डर है जो यहां ध्यान देना महत्वपूर्ण है।

नीचे तैयार बयानों के 2 उदाहरण हैं। पहला एसक्यूएल इंजेक्शन को नहीं रोकेगा।

तैयार किए गए चरण ps = conn.prepareStatement ("उपयोगकर्ताओं से चुनें जहां पहले नाम पसंद है" + नाम);

ऊपर बयान भले ही यह बयान तैयार किया जाता है एसक्यूएल इंजेक्शन

हालांकि नीचे तैयार बयान एसक्यूएल इंजेक्शन को रोकने के लिए अच्छा है नहीं रोकेगा।

तैयार किए गए चरण ps = conn.prepareStatement ("उपयोगकर्ताओं से चुनें जहां पहले नाम पसंद है?");

अंतर बी/डब्ल्यू पहला और दूसरा कथन यह है कि पहले मामले में क्वेरी को गतिशील रूप से रनटाइम पर संकलित किया जाता है लेकिन दूसरे मामले में यह प्रीकंपल किया जाता है।

इसका मतलब है कि दुर्भावनापूर्ण उपयोगकर्ता इनपुट (a'or'1 '=' 1) पहले कथन में क्वेरी को बदल सकता है। लेकिन दूसरी क्वेरी के बाद से प्रीकंपल किया गया है दुर्भावनापूर्ण उपयोगकर्ता इनपुट को डेटा के रूप में और एसक्यूएल कमांड का इलाज नहीं करेगा।

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

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