7

Mã bên dưới là từ SAMATE Reference Dataset. Tôi đã sử dụng nó để kiểm tra một công cụ phân tích tĩnh. Như bạn có thể thấy mã nên ngăn chặn SQL-Injection cả bằng cách sử dụng một phương pháp vệ sinh cũng như sử dụng một tuyên bố chuẩn bị.Câu lệnh chuẩn bị sẵn sàng ngăn SQL-Injection ở đây

Vì các công cụ SCA không thể biết các phương thức santitzation tùy chỉnh, sẽ không phát hiện ra phương pháp allowed được sử dụng để ngăn chặn việc tiêm.

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 
    { 
    } 
} 

Tuy nhiên, tôi nghĩ rằng việc sử dụng câu lệnh chuẩn bị sẽ ngăn chặn việc tiêm ở đây. Tôi có nhầm không?

Trả lời

3

Bạn đã chính xác. prepared statement sẽ xử lý đầu vào SQL 'bất hợp pháp'.

Chức năng allowed(...) là loại xác thực nhập của người dùng về quy tắc kinh doanh chứ không phải để ngăn SQL injection.

+0

Về mặt kỹ thuật, đây là một trục trặc của bản thân tôi. Tôi vô tình nhìn vào kết quả cho dự án sai. Đừng bận tâm. Cảm ơn – er4z0r

1

Chỉ cần báo cáo kết quả chuẩn bị nên là đủ để ngăn chặn SQL injection ...

Tuy nhiên, nếu bạn có ý định viết tin nhắn người sử dụng tham số 'out' (như out.printf("Invalid username %s", name)), xem ra để tiêm javascript. Tôi có thể nhập tên của tôi là <script>alert('hi')</script>

1

Dường như để ngăn SQL Injection. Tất nhiên bạn hoàn toàn chính xác rằng hàm allow() giúp, nhưng không chính xác là phương thức được ưa thích. Vì mã của bạn chỉ là một mẫu, tôi sẽ giả định trong thế giới thực, hầu hết các chương trình sẽ cho phép hơn 5 tùy chọn có thể.

3

Có Báo cáo chuẩn bị ở đây sẽ ngăn chặn việc tiêm sql. Điều này là do bạn đang sử dụng trình giữ chỗ (?) Trong truy vấn. Đó là trình giữ chỗ quan trọng cần lưu ý ở đây.

Dưới đây là 2 ví dụ về báo cáo đã chuẩn bị. Người đầu tiên sẽ không ngăn chặn tiêm sql.

Chuẩn bịStatement ps = conn.prepareStatement ("SELECT * FROM users WHERE firstname LIKE" + name);

Những tuyên bố trên ngay cả khi nó được chuẩn bị tuyên bố sẽ không ngăn cản sql injection

Tuy nhiên, tuyên bố chuẩn bị dưới đây là tốt để ngăn chặn sql injection.

Chuẩn bịStatement ps = conn.prepareStatement ("SELECT * FROM users WHERE firstname LIKE?");

Sự khác biệt b/w câu lệnh đầu tiên và thứ hai là trong khi truy vấn trong trường hợp đầu tiên được biên dịch động trong thời gian chạy nhưng trong trường hợp thứ hai, nó được biên dịch trước.

Điều này có nghĩa là đầu vào người dùng độc hại như (a'or'1 '=' 1) có thể thay đổi truy vấn trong câu lệnh đầu tiên. Nhưng truy vấn thứ hai vì nó được biên dịch trước sẽ xử lý đầu vào người dùng độc hại dưới dạng dữ liệu chứ không phải lệnh sql.

Tóm tắt Các câu lệnh được preapred ngăn SQL Injection nếu và chỉ khi chúng được sử dụng với trình giữ chỗ và tham số liên kết.

Các vấn đề liên quan