Hướng dẫn java sql injection cheat sheet - bảng gian lận java sql injection

Giới thiệu¶

Bài viết này tập trung vào việc cung cấp hướng dẫn rõ ràng, đơn giản, có thể hành động để ngăn ngừa các lỗ hổng tiêm SQL trong các ứng dụng của bạn. Thật không may, các cuộc tấn công SQL là rất phổ biến, và điều này là do hai yếu tố:

  1. Tỷ lệ mắc các lỗ hổng SQL đáng kể và
  2. Sự hấp dẫn của mục tiêu [nghĩa là, cơ sở dữ liệu thường chứa tất cả các dữ liệu thú vị/quan trọng cho ứng dụng của bạn].

Các lỗ hổng SQL được giới thiệu khi các nhà phát triển phần mềm tạo các truy vấn cơ sở dữ liệu động được xây dựng với sự kết hợp chuỗi bao gồm đầu vào do người dùng cung cấp. Để tránh sai sót SQL là đơn giản. Các nhà phát triển cần phải: a] Ngừng viết các truy vấn động bằng cách ghép chuỗi; và/hoặc b] Ngăn chặn đầu vào do người dùng cung cấp có chứa SQL độc hại ảnh hưởng đến logic của truy vấn được thực hiện.

Bài viết này cung cấp một tập hợp các kỹ thuật đơn giản để ngăn ngừa các lỗ hổng SQL bằng cách tránh hai vấn đề này. Những kỹ thuật này có thể được sử dụng với thực tế bất kỳ loại ngôn ngữ lập trình nào với bất kỳ loại cơ sở dữ liệu nào. Có các loại cơ sở dữ liệu khác, như cơ sở dữ liệu XML, có thể có vấn đề tương tự [ví dụ: tiêm XPath và XQuery] và các kỹ thuật này cũng có thể được sử dụng để bảo vệ chúng.

Phòng thủ chính:

  • Tùy chọn 1: Sử dụng các câu lệnh đã chuẩn bị [với các truy vấn được tham số hóa]
  • Tùy chọn 2: Sử dụng các quy trình được lưu trữ được xây dựng đúng
  • Tùy chọn 3: Xác thực đầu vào danh sách cho phép
  • Tùy chọn 4: Thoát tất cả đầu vào do người dùng cung cấp

Phòng thủ bổ sung:

  • Ngoài ra: thực thi đặc quyền ít nhất
  • Ngoài ra: thực hiện xác thực đầu vào danh sách cho phép như một phòng thủ thứ cấp

Ví dụ không an toàn:

Lỗ hổng SQL thường trông như thế này:

Ví dụ [Java] sau đây không an toàn và sẽ cho phép kẻ tấn công tiêm mã vào truy vấn sẽ được thực thi bởi cơ sở dữ liệu. Tham số "Tên tùy chỉnh" không được đánh giá đơn giản được thêm vào truy vấn cho phép kẻ tấn công tiêm bất kỳ mã SQL nào họ muốn. Thật không may, phương pháp này để truy cập cơ sở dữ liệu là quá phổ biến.

String query = "SELECT account_balance FROM user_data WHERE user_name = "
             + request.getParameter["customerName"];
try {
    Statement statement = connection.createStatement[ ... ];
    ResultSet results = statement.executeQuery[ query ];
}
...

Phòng thủ chính Jo

Tùy chọn quốc phòng 1: Các câu lệnh được chuẩn bị [với các truy vấn được tham số hóa] ¶

Việc sử dụng các câu lệnh đã chuẩn bị với ràng buộc biến [hay còn gọi là các truy vấn tham số hóa] là cách tất cả các nhà phát triển trước tiên nên được dạy cách viết các truy vấn cơ sở dữ liệu. Chúng đơn giản để viết, và dễ hiểu hơn các truy vấn động. Các truy vấn được tham số hóa buộc nhà phát triển trước tiên xác định tất cả các mã SQL, sau đó chuyển trong mỗi tham số cho truy vấn sau. Kiểu mã này cho phép cơ sở dữ liệu phân biệt giữa mã và dữ liệu, bất kể đầu vào người dùng nào được cung cấp.

Các câu lệnh được chuẩn bị đảm bảo rằng kẻ tấn công không thể thay đổi mục đích của truy vấn, ngay cả khi các lệnh SQL được chèn bởi kẻ tấn công. Trong ví dụ an toàn dưới đây, nếu kẻ tấn công vào người dùng

// This should REALLY be validated too
String custname = request.getParameter["customerName"];
// Perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.prepareStatement[ query ];
pstmt.setString[ 1, custname];
ResultSet results = pstmt.executeQuery[ ];
8, truy vấn được tham số hóa sẽ không dễ bị tổn thương và thay vào đó sẽ tìm kiếm tên người dùng phù hợp với toàn bộ chuỗi
// This should REALLY be validated too
String custname = request.getParameter["customerName"];
// Perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.prepareStatement[ query ];
pstmt.setString[ 1, custname];
ResultSet results = pstmt.executeQuery[ ];
8.

Khuyến nghị cụ thể về ngôn ngữ:

  • Java EE - Sử dụng
    String query = "SELECT account_balance FROM user_data WHERE user_name = ?";
    try {
      OleDbCommand command = new OleDbCommand[query, connection];
      command.Parameters.Add[new OleDbParameter["customerName", CustomerName Name.Text]];
      OleDbDataReader reader = command.ExecuteReader[];
      // …
    } catch [OleDbException se] {
      // error handling
    }
    
    0 với các biến liên kết
  • .NET - Sử dụng các truy vấn được tham số hóa như
    String query = "SELECT account_balance FROM user_data WHERE user_name = ?";
    try {
      OleDbCommand command = new OleDbCommand[query, connection];
      command.Parameters.Add[new OleDbParameter["customerName", CustomerName Name.Text]];
      OleDbDataReader reader = command.ExecuteReader[];
      // …
    } catch [OleDbException se] {
      // error handling
    }
    
    1 hoặc
    String query = "SELECT account_balance FROM user_data WHERE user_name = ?";
    try {
      OleDbCommand command = new OleDbCommand[query, connection];
      command.Parameters.Add[new OleDbParameter["customerName", CustomerName Name.Text]];
      OleDbDataReader reader = command.ExecuteReader[];
      // …
    } catch [OleDbException se] {
      // error handling
    }
    
    2 với các biến liên kết
  • PHP - Sử dụng PDO với các truy vấn tham số được gõ mạnh [sử dụng BindParam []]
  • Hibernate - Sử dụng
    String query = "SELECT account_balance FROM user_data WHERE user_name = ?";
    try {
      OleDbCommand command = new OleDbCommand[query, connection];
      command.Parameters.Add[new OleDbParameter["customerName", CustomerName Name.Text]];
      OleDbDataReader reader = command.ExecuteReader[];
      // …
    } catch [OleDbException se] {
      // error handling
    }
    
    3 với các biến liên kết [được gọi là tham số được đặt tên trong Hibernate]
  • SQLite - Sử dụng
    String query = "SELECT account_balance FROM user_data WHERE user_name = ?";
    try {
      OleDbCommand command = new OleDbCommand[query, connection];
      command.Parameters.Add[new OleDbParameter["customerName", CustomerName Name.Text]];
      OleDbDataReader reader = command.ExecuteReader[];
      // …
    } catch [OleDbException se] {
      // error handling
    }
    
    4 để tạo đối tượng câu lệnh

Trong những trường hợp hiếm hoi, các tuyên bố chuẩn bị có thể gây hại cho hiệu suất. Khi đối mặt với tình huống này, tốt nhất là a] xác thực mạnh tất cả dữ liệu hoặc b] thoát khỏi tất cả đầu vào được cung cấp của người dùng bằng cách sử dụng thói quen thoát khỏi nhà cung cấp cơ sở dữ liệu của bạn như được mô tả dưới đây, thay vì sử dụng câu lệnh đã chuẩn bị.

Ví dụ về tuyên bố đã chuẩn bị Java an toàn: Ví dụ::

Ví dụ mã sau sử dụng

String query = "SELECT account_balance FROM user_data WHERE user_name = ?";
try {
  OleDbCommand command = new OleDbCommand[query, connection];
  command.Parameters.Add[new OleDbParameter["customerName", CustomerName Name.Text]];
  OleDbDataReader reader = command.ExecuteReader[];
  // …
} catch [OleDbException se] {
  // error handling
}
5, việc triển khai truy vấn được tham số hóa của Java, để thực hiện cùng một truy vấn cơ sở dữ liệu.

// This should REALLY be validated too
String custname = request.getParameter["customerName"];
// Perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.prepareStatement[ query ];
pstmt.setString[ 1, custname];
ResultSet results = pstmt.executeQuery[ ];

Safe C# .NET Chuẩn bị ví dụ::

Với .net, nó thậm chí còn đơn giản hơn. Việc tạo và thực hiện truy vấn không thay đổi. Tất cả những gì bạn phải làm chỉ đơn giản là chuyển các tham số cho truy vấn bằng cách sử dụng cuộc gọi

String query = "SELECT account_balance FROM user_data WHERE user_name = ?";
try {
  OleDbCommand command = new OleDbCommand[query, connection];
  command.Parameters.Add[new OleDbParameter["customerName", CustomerName Name.Text]];
  OleDbDataReader reader = command.ExecuteReader[];
  // …
} catch [OleDbException se] {
  // error handling
}
6 như được hiển thị ở đây.

String query = "SELECT account_balance FROM user_data WHERE user_name = ?";
try {
  OleDbCommand command = new OleDbCommand[query, connection];
  command.Parameters.Add[new OleDbParameter["customerName", CustomerName Name.Text]];
  OleDbDataReader reader = command.ExecuteReader[];
  // …
} catch [OleDbException se] {
  // error handling
}

Chúng tôi đã hiển thị các ví dụ trong Java và .NET nhưng thực tế tất cả các ngôn ngữ khác, bao gồm Fusion Fusion và Cổ điển ASP, hỗ trợ các giao diện truy vấn tham số hóa. Ngay cả các lớp trừu tượng SQL, như ngôn ngữ truy vấn ngủ đông [HQL] cũng có cùng loại vấn đề tiêm [mà chúng ta gọi là tiêm HQL]. HQL cũng hỗ trợ các truy vấn được tham số hóa, vì vậy chúng tôi có thể tránh được vấn đề này:

Ngôn ngữ truy vấn Hibernate [HQL] đã chuẩn bị [tham số được đặt tên] Ví dụ::

//First is an unsafe HQL Statement
Query unsafeHQLQuery = session.createQuery["from Inventory where productID='"+userSuppliedParameter+"'"];
//Here is a safe version of the same query using named parameters
Query safeHQLQuery = session.createQuery["from Inventory where productID=:productid"];
safeHQLQuery.setParameter["productid", userSuppliedParameter];

Ví dụ về các truy vấn được tham số hóa trong các ngôn ngữ khác, bao gồm Ruby, PHP, Fusion Fusion và Perl, hãy xem bảng gian lận tham số truy vấn hoặc trang web này.

Các nhà phát triển có xu hướng thích cách tiếp cận câu lệnh đã chuẩn bị vì tất cả các mã SQL đều nằm trong ứng dụng. Điều này làm cho ứng dụng của bạn tương đối độc lập cơ sở dữ liệu.

Tùy chọn quốc phòng 2: Thủ tục lưu trữ Jo

Các thủ tục được lưu trữ không phải lúc nào cũng an toàn với SQL tiêm. Tuy nhiên, một số cấu trúc lập trình thủ tục được lưu trữ tiêu chuẩn nhất định có tác dụng tương tự như việc sử dụng các truy vấn được tham số hóa khi được triển khai một cách an toàn, đó là tiêu chuẩn cho hầu hết các ngôn ngữ thủ tục được lưu trữ.

Họ yêu cầu nhà phát triển chỉ xây dựng các câu lệnh SQL với các tham số được tự động tham số hóa trừ khi nhà phát triển thực hiện một cái gì đó phần lớn nằm ngoài định mức. Sự khác biệt giữa các câu lệnh đã chuẩn bị và các quy trình được lưu trữ là mã SQL cho quy trình được lưu trữ được xác định và lưu trữ trong chính cơ sở dữ liệu, và sau đó được gọi từ ứng dụng. Cả hai kỹ thuật này đều có hiệu quả tương tự trong việc ngăn ngừa tiêm SQL để tổ chức của bạn nên chọn cách tiếp cận nào có ý nghĩa nhất đối với bạn.

Lưu ý: 'Được triển khai một cách an toàn' có nghĩa là quy trình được lưu trữ không bao gồm bất kỳ thế hệ SQL động không an toàn nào. Các nhà phát triển thường không tạo SQL động bên trong các thủ tục được lưu trữ. Tuy nhiên, nó có thể được thực hiện, nhưng nên tránh. Nếu không thể tránh được, quy trình được lưu trữ phải sử dụng xác thực đầu vào hoặc thoát thích hợp như được mô tả trong bài viết này để đảm bảo rằng tất cả người dùng được cung cấp đầu vào cho quy trình được lưu trữ không thể được sử dụng để đưa mã SQL vào truy vấn được tạo động. Kiểm toán viên luôn luôn tìm kiếm việc sử dụng SP_EXECUTE, EXECUTE hoặc EXEC trong các quy trình lưu trữ SQL Server. Hướng dẫn kiểm toán tương tự là cần thiết cho các chức năng tương tự cho các nhà cung cấp khác.

Ngoài ra còn có một số trường hợp các thủ tục lưu trữ có thể làm tăng rủi ro. Ví dụ: trên MS SQL Server, bạn có 3 vai trò mặc định chính:

String query = "SELECT account_balance FROM user_data WHERE user_name = ?";
try {
  OleDbCommand command = new OleDbCommand[query, connection];
  command.Parameters.Add[new OleDbParameter["customerName", CustomerName Name.Text]];
  OleDbDataReader reader = command.ExecuteReader[];
  // …
} catch [OleDbException se] {
  // error handling
}
7,
String query = "SELECT account_balance FROM user_data WHERE user_name = ?";
try {
  OleDbCommand command = new OleDbCommand[query, connection];
  command.Parameters.Add[new OleDbParameter["customerName", CustomerName Name.Text]];
  OleDbDataReader reader = command.ExecuteReader[];
  // …
} catch [OleDbException se] {
  // error handling
}
8 và
String query = "SELECT account_balance FROM user_data WHERE user_name = ?";
try {
  OleDbCommand command = new OleDbCommand[query, connection];
  command.Parameters.Add[new OleDbParameter["customerName", CustomerName Name.Text]];
  OleDbDataReader reader = command.ExecuteReader[];
  // …
} catch [OleDbException se] {
  // error handling
}
9. Trước khi các thủ tục được lưu trữ được sử dụng, DBA sẽ cung cấp cho DB_DatareAder hoặc DB_Datawriter quyền cho người dùng của WebService, tùy thuộc vào các yêu cầu. Tuy nhiên, các thủ tục được lưu trữ yêu cầu quyền thực thi, một vai trò không có sẵn theo mặc định. Một số thiết lập trong đó quản lý người dùng đã được tập trung, nhưng được giới hạn trong 3 vai trò đó, khiến tất cả các ứng dụng web chạy theo quyền của DB_OWNER để các thủ tục được lưu trữ có thể hoạt động. Đương nhiên, điều đó có nghĩa là nếu một máy chủ bị vi phạm, kẻ tấn công có toàn quyền đối với cơ sở dữ liệu, nơi trước đây họ có thể chỉ có truy cập đọc.

Ví dụ về thủ tục lưu trữ Java an toàn: Ví dụ::

Ví dụ mã sau sử dụng

//First is an unsafe HQL Statement
Query unsafeHQLQuery = session.createQuery["from Inventory where productID='"+userSuppliedParameter+"'"];
//Here is a safe version of the same query using named parameters
Query safeHQLQuery = session.createQuery["from Inventory where productID=:productid"];
safeHQLQuery.setParameter["productid", userSuppliedParameter];
0, việc triển khai giao diện thủ tục được lưu trữ của Java, để thực hiện cùng một truy vấn cơ sở dữ liệu. Quy trình được lưu trữ
//First is an unsafe HQL Statement
Query unsafeHQLQuery = session.createQuery["from Inventory where productID='"+userSuppliedParameter+"'"];
//Here is a safe version of the same query using named parameters
Query safeHQLQuery = session.createQuery["from Inventory where productID=:productid"];
safeHQLQuery.setParameter["productid", userSuppliedParameter];
1 sẽ phải được xác định trước trong cơ sở dữ liệu và thực hiện chức năng tương tự như truy vấn được xác định ở trên.

// This should REALLY be validated
String custname = request.getParameter["customerName"];
try {
  CallableStatement cs = connection.prepareCall["{call sp_getAccountBalance[?]}"];
  cs.setString[1, custname];
  ResultSet results = cs.executeQuery[];
  // … result set handling
} catch [SQLException se] {
  // … logging and error handling
}

Ví dụ quy trình lưu trữ VB .NET an toàn::

Ví dụ mã sau sử dụng

//First is an unsafe HQL Statement
Query unsafeHQLQuery = session.createQuery["from Inventory where productID='"+userSuppliedParameter+"'"];
//Here is a safe version of the same query using named parameters
Query safeHQLQuery = session.createQuery["from Inventory where productID=:productid"];
safeHQLQuery.setParameter["productid", userSuppliedParameter];
2, triển khai của .NET của giao diện thủ tục được lưu trữ, để thực hiện cùng một truy vấn cơ sở dữ liệu. Quy trình được lưu trữ
//First is an unsafe HQL Statement
Query unsafeHQLQuery = session.createQuery["from Inventory where productID='"+userSuppliedParameter+"'"];
//Here is a safe version of the same query using named parameters
Query safeHQLQuery = session.createQuery["from Inventory where productID=:productid"];
safeHQLQuery.setParameter["productid", userSuppliedParameter];
1 sẽ phải được xác định trước trong cơ sở dữ liệu và thực hiện chức năng tương tự như truy vấn được xác định ở trên.

 Try
   Dim command As SqlCommand = new SqlCommand["sp_getAccountBalance", connection]
   command.CommandType = CommandType.StoredProcedure
   command.Parameters.Add[new SqlParameter["@CustomerName", CustomerName.Text]]
   Dim reader As SqlDataReader = command.ExecuteReader[]
   '...
 Catch se As SqlException
   'error handling
 End Try

Tùy chọn quốc phòng 3: Xác thực đầu vào danh sách cho phép

Các phần khác nhau của các truy vấn SQL không phải là các vị trí hợp pháp cho việc sử dụng các biến liên kết, chẳng hạn như tên của các bảng hoặc cột và chỉ báo thứ tự sắp xếp [ASC hoặc DESC]. Trong các tình huống như vậy, xác thực đầu vào hoặc thiết kế lại truy vấn là phòng thủ phù hợp nhất. Đối với tên của các bảng hoặc cột, lý tưởng, các giá trị đó đến từ mã và không phải từ các tham số người dùng.

Nhưng nếu các giá trị tham số người dùng được sử dụng để nhắm mục tiêu các tên bảng và tên cột khác nhau, thì các giá trị tham số sẽ được ánh xạ tới bảng hợp pháp/dự kiến ​​hoặc tên cột để đảm bảo đầu vào người dùng không được đánh giá không kết thúc trong truy vấn. Xin lưu ý, đây là một triệu chứng của thiết kế kém và cần viết lại đầy đủ nếu thời gian cho phép.

Dưới đây là một ví dụ về xác thực tên bảng.

String tableName;
switch[PARAM]:
  case "Value1": tableName = "fooTable";
                 break;
  case "Value2": tableName = "barTable";
                 break;
  ...
  default      : throw new InputValidationException["unexpected value provided"
                                                  + " for table name"];

//First is an unsafe HQL Statement
Query unsafeHQLQuery = session.createQuery["from Inventory where productID='"+userSuppliedParameter+"'"];
//Here is a safe version of the same query using named parameters
Query safeHQLQuery = session.createQuery["from Inventory where productID=:productid"];
safeHQLQuery.setParameter["productid", userSuppliedParameter];
4 sau đó có thể được nối trực tiếp vào truy vấn SQL vì hiện tại nó được biết đến là một trong những giá trị hợp pháp và mong đợi cho một tên bảng trong truy vấn này. Hãy nhớ rằng các chức năng xác thực bảng chung có thể dẫn đến mất dữ liệu khi tên bảng được sử dụng trong các truy vấn mà chúng không được mong đợi.

Đối với một cái gì đó đơn giản như một thứ tự sắp xếp, sẽ là tốt nhất nếu người dùng cung cấp đầu vào được chuyển đổi thành boolean, và sau đó boolean được sử dụng để chọn giá trị an toàn để nối vào truy vấn. Đây là một nhu cầu rất chuẩn trong việc tạo truy vấn động.

Ví dụ:

public String someMethod[boolean sortOrder] {
 String SQLquery = "some SQL ... order by Salary " + [sortOrder ? "ASC" : "DESC"];`
 ...

Bất kỳ đầu vào người dùng thời gian nào cũng có thể được chuyển đổi thành không chuỗi, như một ngày, số, số, boolean, loại được liệt kê, v.v. an toàn để làm như vậy.

Xác thực đầu vào cũng được khuyến nghị là một biện pháp bảo vệ thứ cấp trong mọi trường hợp, ngay cả khi sử dụng các biến liên kết như được thảo luận sau trong bài viết này. Nhiều kỹ thuật về cách thực hiện xác thực đầu vào mạnh được mô tả trong bảng cheat xác thực đầu vào.

Tùy chọn phòng thủ 4: Thoát tất cả đầu vào do người dùng cung cấp

Kỹ thuật này chỉ nên được sử dụng như là phương sách cuối cùng, khi không có phương pháp nào ở trên là khả thi. Xác thực đầu vào có lẽ là một lựa chọn tốt hơn vì phương pháp này yếu so với các phòng thủ khác và chúng tôi không thể đảm bảo nó sẽ ngăn chặn tất cả các SQL tiêm trong tất cả các tình huống.

Kỹ thuật này là để thoát khỏi đầu vào của người dùng trước khi đặt nó vào một truy vấn. Nó rất cụ thể trong cơ sở dữ liệu trong việc thực hiện của nó. Nó thường chỉ được khuyến nghị trang bị thêm mã di sản khi thực hiện xác thực đầu vào không hiệu quả về chi phí. Các ứng dụng được xây dựng từ đầu, hoặc các ứng dụng yêu cầu dung sai rủi ro thấp nên được xây dựng hoặc viết lại bằng cách sử dụng các truy vấn được tham số hóa, quy trình lưu trữ hoặc một số loại Mapper quan hệ đối tượng [ORM] xây dựng các truy vấn của bạn cho bạn.

Kỹ thuật này hoạt động như thế này. Mỗi DBMS hỗ trợ một hoặc nhiều sơ đồ thoát khỏi ký tự cụ thể cho các loại truy vấn nhất định. Sau đó, nếu bạn thoát khỏi tất cả các đầu vào do người dùng cung cấp bằng cách sử dụng sơ đồ thoát thích hợp cho cơ sở dữ liệu bạn đang sử dụng, DBMS sẽ không nhầm lẫn đầu vào đó với mã SQL được viết bởi nhà phát triển, do đó tránh mọi lỗ hổng SQL có thể có.

API bảo mật doanh nghiệp OWASP [ESAPI] là một thư viện kiểm soát bảo mật ứng dụng web miễn phí, miễn phí, giúp các lập trình viên dễ dàng viết các ứng dụng rủi ro thấp hơn. Các thư viện ESAPI được thiết kế để giúp các lập trình viên dễ dàng hơn trong việc trang bị lại bảo mật thành các ứng dụng hiện có. Các thư viện ESAPI cũng đóng vai trò là nền tảng vững chắc cho sự phát triển mới:

  • Chi tiết đầy đủ về ESAPI có sẵn ở đây trên OWASP.
  • Javadoc cho ESAPI 2.x [Legacy] có sẵn. Mã này đã được di chuyển sang GitHub vào tháng 11 năm 2014.
  • ESAPI di sản cho Java tại GitHub giúp hiểu được việc sử dụng nó hiện tại khi Javadoc dường như không đủ.
  • Một nỗ lực tại một ESAPI khác cho Java GitHub có các cách tiếp cận khác và không có xét nghiệm hoặc codec cụ thể.

Để tìm Javadoc đặc biệt cho bộ mã hóa cơ sở dữ liệu, hãy nhấp vào lớp

//First is an unsafe HQL Statement
Query unsafeHQLQuery = session.createQuery["from Inventory where productID='"+userSuppliedParameter+"'"];
//Here is a safe version of the same query using named parameters
Query safeHQLQuery = session.createQuery["from Inventory where productID=:productid"];
safeHQLQuery.setParameter["productid", userSuppliedParameter];
5 ở phía bên trái. Có rất nhiều codec được thực hiện. Hai codec cụ thể của cơ sở dữ liệu là
//First is an unsafe HQL Statement
Query unsafeHQLQuery = session.createQuery["from Inventory where productID='"+userSuppliedParameter+"'"];
//Here is a safe version of the same query using named parameters
Query safeHQLQuery = session.createQuery["from Inventory where productID=:productid"];
safeHQLQuery.setParameter["productid", userSuppliedParameter];
6 và
//First is an unsafe HQL Statement
Query unsafeHQLQuery = session.createQuery["from Inventory where productID='"+userSuppliedParameter+"'"];
//Here is a safe version of the same query using named parameters
Query safeHQLQuery = session.createQuery["from Inventory where productID=:productid"];
safeHQLQuery.setParameter["productid", userSuppliedParameter];
7.

Chỉ cần nhấp vào tên của họ trong

//First is an unsafe HQL Statement
Query unsafeHQLQuery = session.createQuery["from Inventory where productID='"+userSuppliedParameter+"'"];
//Here is a safe version of the same query using named parameters
Query safeHQLQuery = session.createQuery["from Inventory where productID=:productid"];
safeHQLQuery.setParameter["productid", userSuppliedParameter];
8 ở đầu trang codec giao diện.

Tại thời điểm này, ESAPI hiện có bộ mã hóa cơ sở dữ liệu cho:

  • Oracle
  • MySQL [cả ANSI và chế độ gốc đều được hỗ trợ]

Bộ mã hóa cơ sở dữ liệu sắp tới cho:

  • Máy chủ SQL
  • Postgresql

Nếu bộ mã hóa cơ sở dữ liệu của bạn bị thiếu, xin vui lòng cho chúng tôi biết.

Cơ sở dữ liệu Chi tiết thoát khỏi cơ sở dữ liệu

Nếu bạn muốn xây dựng các thói quen thoát ra của riêng mình, đây là các chi tiết thoát ra cho từng cơ sở dữ liệu mà chúng tôi đã phát triển bộ mã hóa ESAPI cho:

  • Oracle
  • Máy chủ SQL
  • DB2
Postgresql

Nếu bộ mã hóa cơ sở dữ liệu của bạn bị thiếu, xin vui lòng cho chúng tôi biết.

Cơ sở dữ liệu Chi tiết thoát khỏi cơ sở dữ liệu

Nếu bạn muốn xây dựng các thói quen thoát ra của riêng mình, đây là các chi tiết thoát ra cho từng cơ sở dữ liệu mà chúng tôi đã phát triển bộ mã hóa ESAPI cho:

ESAPI.encoder[].encodeForSQL[ new OracleCodec[], queryparam ];

Oracle Escaping¶

String query = "SELECT user_id FROM user_data WHERE user_name = '"
              + req.getParameter["userID"]
              + "' and user_password = '" + req.getParameter["pwd"] +"'";
try {
    Statement statement = connection.createStatement[  ];
    ResultSet results = statement.executeQuery[ query ];
}

Thông tin này dựa trên thông tin nhân vật Escape Oracle.

Thoát khỏi các truy vấn động

Để sử dụng codec cơ sở dữ liệu ESAPI khá đơn giản. Một ví dụ về Oracle trông giống như:

Vì vậy, nếu bạn có một truy vấn động hiện có được tạo trong mã của bạn sẽ đến Oracle trông như thế này:

// This should REALLY be validated too
String custname = request.getParameter["customerName"];
// Perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.prepareStatement[ query ];
pstmt.setString[ 1, custname];
ResultSet results = pstmt.executeQuery[ ];
1

Bạn sẽ viết lại dòng đầu tiên trông như thế này:

// This should REALLY be validated too
String custname = request.getParameter["customerName"];
// Perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.prepareStatement[ query ];
pstmt.setString[ 1, custname];
ResultSet results = pstmt.executeQuery[ ];
0

Và bây giờ nó sẽ an toàn với SQL Injection, bất kể đầu vào được cung cấp.

Để có khả năng đọc mã tối đa, bạn cũng có thể xây dựng

//First is an unsafe HQL Statement
Query unsafeHQLQuery = session.createQuery["from Inventory where productID='"+userSuppliedParameter+"'"];
//Here is a safe version of the same query using named parameters
Query safeHQLQuery = session.createQuery["from Inventory where productID=:productid"];
safeHQLQuery.setParameter["productid", userSuppliedParameter];
9 của riêng bạn:

Với loại giải pháp này, bạn chỉ cần kết thúc từng tham số do người dùng cung cấp được chuyển vào cuộc gọi
// This should REALLY be validated
String custname = request.getParameter["customerName"];
try {
  CallableStatement cs = connection.prepareCall["{call sp_getAccountBalance[?]}"];
  cs.setString[1, custname];
  ResultSet results = cs.executeQuery[];
  // … result set handling
} catch [SQLException se] {
  // … logging and error handling
}
0 hoặc bất cứ điều gì bạn đặt tên cho cuộc gọi và bạn sẽ được thực hiện.

Tắt thay thế ký tự

Sử dụng

// This should REALLY be validated
String custname = request.getParameter["customerName"];
try {
  CallableStatement cs = connection.prepareCall["{call sp_getAccountBalance[?]}"];
  cs.setString[1, custname];
  ResultSet results = cs.executeQuery[];
  // … result set handling
} catch [SQLException se] {
  // … logging and error handling
}
1 hoặc
// This should REALLY be validated
String custname = request.getParameter["customerName"];
try {
  CallableStatement cs = connection.prepareCall["{call sp_getAccountBalance[?]}"];
  cs.setString[1, custname];
  ResultSet results = cs.executeQuery[];
  // … result set handling
} catch [SQLException se] {
  // … logging and error handling
}
2 để đảm bảo tắt thay thế ký tự tự động. Nếu thay thế ký tự này được bật, & ký tự sẽ được đối xử như tiền tố biến SQLPLUS có thể cho phép kẻ tấn công truy xuất dữ liệu riêng tư.

// This should REALLY be validated too
String custname = request.getParameter["customerName"];
// Perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.prepareStatement[ query ];
pstmt.setString[ 1, custname];
ResultSet results = pstmt.executeQuery[ ];
2

Xem ở đây và ở đây để biết thêm thông tin

Thoát khỏi ký tự ký tự đại diện trong giống như mệnh đề

MySQL Escaping¶

MySQL hỗ trợ hai chế độ thoát:

  1.  Try
       Dim command As SqlCommand = new SqlCommand["sp_getAccountBalance", connection]
       command.CommandType = CommandType.StoredProcedure
       command.Parameters.Add[new SqlParameter["@CustomerName", CustomerName.Text]]
       Dim reader As SqlDataReader = command.ExecuteReader[]
       '...
     Catch se As SqlException
       'error handling
     End Try
    
    0 Chế độ SQL và chế độ với điều này, chúng tôi gọi là
  2. Chế độ
     Try
       Dim command As SqlCommand = new SqlCommand["sp_getAccountBalance", connection]
       command.CommandType = CommandType.StoredProcedure
       command.Parameters.Add[new SqlParameter["@CustomerName", CustomerName.Text]]
       Dim reader As SqlDataReader = command.ExecuteReader[]
       '...
     Catch se As SqlException
       'error handling
     End Try
    
    1.

Chế độ

 Try
   Dim command As SqlCommand = new SqlCommand["sp_getAccountBalance", connection]
   command.CommandType = CommandType.StoredProcedure
   command.Parameters.Add[new SqlParameter["@CustomerName", CustomerName.Text]]
   Dim reader As SqlDataReader = command.ExecuteReader[]
   '...
 Catch se As SqlException
   'error handling
 End Try
2: Đơn giản chỉ cần mã hóa tất cả các ký tự
 Try
   Dim command As SqlCommand = new SqlCommand["sp_getAccountBalance", connection]
   command.CommandType = CommandType.StoredProcedure
   command.Parameters.Add[new SqlParameter["@CustomerName", CustomerName.Text]]
   Dim reader As SqlDataReader = command.ExecuteReader[]
   '...
 Catch se As SqlException
   'error handling
 End Try
3 [đánh dấu đơn] với
 Try
   Dim command As SqlCommand = new SqlCommand["sp_getAccountBalance", connection]
   command.CommandType = CommandType.StoredProcedure
   command.Parameters.Add[new SqlParameter["@CustomerName", CustomerName.Text]]
   Dim reader As SqlDataReader = command.ExecuteReader[]
   '...
 Catch se As SqlException
   'error handling
 End Try
4 [hai ve đơn]

Chế độ

 Try
   Dim command As SqlCommand = new SqlCommand["sp_getAccountBalance", connection]
   command.CommandType = CommandType.StoredProcedure
   command.Parameters.Add[new SqlParameter["@CustomerName", CustomerName.Text]]
   Dim reader As SqlDataReader = command.ExecuteReader[]
   '...
 Catch se As SqlException
   'error handling
 End Try
1, làm như sau:

// This should REALLY be validated too
String custname = request.getParameter["customerName"];
// Perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.prepareStatement[ query ];
pstmt.setString[ 1, custname];
ResultSet results = pstmt.executeQuery[ ];
3

Thông tin này dựa trên thông tin ký tự thoát MySQL.

SQL Server Escaping¶

Chúng tôi chưa triển khai thói quen thoát SQL Server, nhưng sau đây có các gợi ý và liên kết tốt đến các bài viết mô tả cách ngăn chặn các cuộc tấn công tiêm SQL trên SQL Server, xem tại đây.

DB2 Escaping¶

Thông tin này dựa trên các ký tự đặc biệt của DB2 WebQuery cũng như một số thông tin từ trình điều khiển JDBC DB2 của Oracle.

Thông tin liên quan đến sự khác biệt giữa một số trình điều khiển phổ biến DB2.

Mã hóa hex tất cả đầu vào

Một trường hợp đặc biệt của việc trốn thoát là quá trình mã hóa hex toàn bộ chuỗi nhận được từ người dùng [điều này có thể được coi là thoát khỏi mọi ký tự]. Ứng dụng Web nên mã hóa hex đầu vào của người dùng trước khi bao gồm nó trong câu lệnh SQL. Câu lệnh SQL nên tính đến thực tế này và theo đó so sánh dữ liệu.

Ví dụ: nếu chúng ta phải tra cứu một bản ghi khớp với sessionID và người dùng đã truyền chuỗi ABC123 làm ID phiên, câu lệnh SELECT sẽ là:

// This should REALLY be validated too
String custname = request.getParameter["customerName"];
// Perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.prepareStatement[ query ];
pstmt.setString[ 1, custname];
ResultSet results = pstmt.executeQuery[ ];
4

 Try
   Dim command As SqlCommand = new SqlCommand["sp_getAccountBalance", connection]
   command.CommandType = CommandType.StoredProcedure
   command.Parameters.Add[new SqlParameter["@CustomerName", CustomerName.Text]]
   Dim reader As SqlDataReader = command.ExecuteReader[]
   '...
 Catch se As SqlException
   'error handling
 End Try
6 nên được thay thế bằng cơ sở cụ thể cho cơ sở dữ liệu đang được sử dụng. Chuỗi 606162313233 là phiên bản được mã hóa HEX của chuỗi nhận được từ người dùng [đó là chuỗi các giá trị HEX của mã ASCII/UTF-8 của dữ liệu người dùng].

Nếu kẻ tấn công truyền một chuỗi chứa một ký tự đơn lẻ theo sau là nỗ lực của họ để tiêm mã SQL, câu lệnh SQL được xây dựng sẽ chỉ trông giống như:

// This should REALLY be validated too
String custname = request.getParameter["customerName"];
// Perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.prepareStatement[ query ];
pstmt.setString[ 1, custname];
ResultSet results = pstmt.executeQuery[ ];
5

 Try
   Dim command As SqlCommand = new SqlCommand["sp_getAccountBalance", connection]
   command.CommandType = CommandType.StoredProcedure
   command.Parameters.Add[new SqlParameter["@CustomerName", CustomerName.Text]]
   Dim reader As SqlDataReader = command.ExecuteReader[]
   '...
 Catch se As SqlException
   'error handling
 End Try
7 là mã ASCII [tính bằng HEX] của quote đơn, đơn giản là được mã hóa hex như bất kỳ ký tự nào khác trong chuỗi. SQL kết quả chỉ có thể chứa các chữ số và chữ số
 Try
   Dim command As SqlCommand = new SqlCommand["sp_getAccountBalance", connection]
   command.CommandType = CommandType.StoredProcedure
   command.Parameters.Add[new SqlParameter["@CustomerName", CustomerName.Text]]
   Dim reader As SqlDataReader = command.ExecuteReader[]
   '...
 Catch se As SqlException
   'error handling
 End Try
8 đến
 Try
   Dim command As SqlCommand = new SqlCommand["sp_getAccountBalance", connection]
   command.CommandType = CommandType.StoredProcedure
   command.Parameters.Add[new SqlParameter["@CustomerName", CustomerName.Text]]
   Dim reader As SqlDataReader = command.ExecuteReader[]
   '...
 Catch se As SqlException
   'error handling
 End Try
9, và không bao giờ bất kỳ ký tự đặc biệt nào có thể cho phép tiêm SQL.

Thoát SQLI trong Php¶

Sử dụng các câu lệnh đã chuẩn bị và truy vấn tham số hóa. Đây là các câu lệnh SQL được gửi đến và phân tích cú pháp bởi máy chủ cơ sở dữ liệu tách biệt với bất kỳ tham số nào. Bằng cách này, một kẻ tấn công không thể tiêm SQL độc hại.

Về cơ bản, bạn có hai tùy chọn để đạt được điều này:

  1. Sử dụng PDO [cho bất kỳ trình điều khiển cơ sở dữ liệu được hỗ trợ nào]:

// This should REALLY be validated too
String custname = request.getParameter["customerName"];
// Perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.prepareStatement[ query ];
pstmt.setString[ 1, custname];
ResultSet results = pstmt.executeQuery[ ];
6

  1. Sử dụng MySQLI [cho MySQL]:

// This should REALLY be validated too
String custname = request.getParameter["customerName"];
// Perform input validation to detect attacks
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.prepareStatement[ query ];
pstmt.setString[ 1, custname];
ResultSet results = pstmt.executeQuery[ ];
7

PDO là tùy chọn phổ quát. Nếu bạn đang kết nối với cơ sở dữ liệu khác với MySQL, bạn có thể tham khảo tùy chọn thứ hai dành riêng cho trình điều khiển [ví dụ: pg_prepare [] và pg_execute [] cho postgresql].

Phòng thủ bổ sung Jo

Ngoài việc áp dụng một trong bốn biện pháp phòng thủ chính, chúng tôi cũng khuyên bạn nên áp dụng tất cả các phòng thủ bổ sung này để cung cấp phòng thủ theo chiều sâu. Những phòng thủ bổ sung này là:

  • Đặc quyền nhất
  • Cho phép xác thực đầu vào danh sách

Đặc quyền nhất¶

Để giảm thiểu thiệt hại tiềm tàng của một cuộc tấn công tiêm SQL thành công, bạn nên giảm thiểu các đặc quyền được gán cho mọi tài khoản cơ sở dữ liệu trong môi trường của bạn. Không chỉ định quyền truy cập loại DBA hoặc quản trị viên cho tài khoản ứng dụng của bạn. Chúng tôi hiểu rằng điều này là dễ dàng, và mọi thứ chỉ là 'hoạt động' khi bạn làm theo cách này, nhưng nó rất nguy hiểm.

Bắt đầu từ cơ sở để xác định quyền truy cập mà tài khoản ứng dụng của bạn yêu cầu, thay vì cố gắng tìm ra những quyền truy cập bạn cần lấy đi. Đảm bảo rằng các tài khoản chỉ cần truy cập đọc chỉ được cấp quyền truy cập đọc cho các bảng họ cần truy cập.

Nếu một tài khoản chỉ cần truy cập vào các phần của bảng, hãy xem xét việc tạo chế độ xem giới hạn quyền truy cập vào phần đó của dữ liệu và thay thế việc gán quyền truy cập tài khoản vào chế độ xem, thay vì bảng bên dưới. Hiếm khi, nếu có, hãy cấp hoặc xóa quyền truy cập vào tài khoản cơ sở dữ liệu.

Nếu bạn áp dụng chính sách mà bạn sử dụng các quy trình được lưu trữ ở mọi nơi và không cho phép các tài khoản ứng dụng thực hiện trực tiếp các truy vấn của riêng họ, thì hãy hạn chế các tài khoản đó để chỉ có thể thực hiện các quy trình được lưu trữ mà họ cần. Đừng cấp cho họ bất kỳ quyền trực tiếp cho các bảng trong cơ sở dữ liệu.

SQL Injection không phải là mối đe dọa duy nhất đối với dữ liệu cơ sở dữ liệu của bạn. Những kẻ tấn công chỉ cần thay đổi các giá trị tham số từ một trong các giá trị pháp lý mà chúng được trình bày, thành một giá trị không được phép đối với chúng, nhưng bản thân ứng dụng có thể được ủy quyền truy cập. Do đó, giảm thiểu các đặc quyền được cấp cho ứng dụng của bạn sẽ giảm khả năng các nỗ lực truy cập trái phép như vậy, ngay cả khi kẻ tấn công không cố gắng sử dụng tiêm SQL như một phần của khai thác.

Trong khi bạn đang ở đó, bạn nên giảm thiểu các đặc quyền của tài khoản hệ điều hành mà DBMS chạy theo. Đừng chạy DBMS của bạn dưới dạng gốc hoặc hệ thống! Hầu hết các DBMS chạy ra khỏi hộp với một tài khoản hệ thống rất mạnh. Ví dụ: MySQL chạy dưới dạng hệ thống trên Windows theo mặc định! Thay đổi tài khoản HĐH của DBMS thành một cái gì đó phù hợp hơn, với các đặc quyền bị hạn chế.

Nhiều người dùng DB

Nhà thiết kế các ứng dụng web không chỉ nên tránh sử dụng cùng một tài khoản chủ sở hữu/quản trị viên trong các ứng dụng web để kết nối với cơ sở dữ liệu. Người dùng DB khác nhau có thể được sử dụng cho các ứng dụng web khác nhau.

Nói chung, mỗi ứng dụng web riêng biệt yêu cầu truy cập vào cơ sở dữ liệu có thể có tài khoản người dùng cơ sở dữ liệu được chỉ định mà ứng dụng web sẽ sử dụng để kết nối với DB. Bằng cách đó, người thiết kế ứng dụng có thể có độ chi tiết tốt trong điều khiển truy cập, do đó làm giảm các đặc quyền càng nhiều càng tốt. Mỗi người dùng DB sau đó sẽ chỉ chọn quyền truy cập vào những gì nó cần và truy cập ghi khi cần thiết.

Ví dụ, trang đăng nhập yêu cầu đọc quyền truy cập vào các trường người dùng và mật khẩu của bảng, nhưng không có quyền truy cập ghi của bất kỳ biểu mẫu nào [không chèn, cập nhật hoặc xóa]. Tuy nhiên, trang đăng ký chắc chắn đòi hỏi đặc quyền chèn vào bảng đó; Hạn chế này chỉ có thể được thực thi nếu các ứng dụng web này sử dụng người dùng DB khác nhau để kết nối với cơ sở dữ liệu.

Lượt xem¶

Bạn có thể sử dụng các chế độ xem SQL để tăng thêm độ chi tiết của truy cập bằng cách giới hạn quyền truy cập đọc vào các trường cụ thể của bảng hoặc nối các bảng. Nó có khả năng có thêm lợi ích: ví dụ, giả sử rằng hệ thống là bắt buộc [có lẽ do một số yêu cầu pháp lý cụ thể] để lưu trữ mật khẩu của người dùng, thay vì mật khẩu bị muối.

Nhà thiết kế có thể sử dụng các quan điểm để bù đắp cho giới hạn này; Thu hồi tất cả quyền truy cập vào bảng [từ tất cả người dùng DB ngoại trừ chủ sở hữu/quản trị viên] và tạo chế độ xem xuất ra băm của trường mật khẩu chứ không phải chính trường. Bất kỳ cuộc tấn công tiêm SQL nào thành công trong việc đánh cắp thông tin DB sẽ bị hạn chế đánh cắp hàm băm của mật khẩu [thậm chí có thể là một hàm băm có khóa], vì không có người dùng DB nào cho bất kỳ ứng dụng web nào có quyền truy cập vào bảng.

Cho phép xác nhận đầu vào danh sách

Ngoài việc là một biện pháp bảo vệ chính khi không có gì khác [ví dụ: khi một biến ràng buộc không hợp pháp], xác thực đầu vào cũng có thể là một biện pháp phòng thủ thứ cấp được sử dụng để phát hiện đầu vào trái phép trước khi được chuyển cho truy vấn SQL. Để biết thêm thông tin, vui lòng xem bảng cheat xác thực đầu vào. Tiến hành thận trọng ở đây. Dữ liệu được xác thực không nhất thiết phải an toàn để chèn vào các truy vấn SQL thông qua việc xây dựng chuỗi.

Những bài viết liên quan¶

SQL Injection Attack Sheets::

Các bài viết sau đây mô tả cách khai thác các loại lỗ hổng SQL khác nhau trên các nền tảng khác nhau mà bài viết này được tạo ra để giúp bạn tránh:

  • SQL Injection Sheet
  • Bỏ qua WAF của SQLI - SQL tiêm Bỏ qua WAF

Mô tả các lỗ hổng tiêm SQL::

  • OWASP Bài viết về lỗ hổng SQL
  • OWASP Bài viết về BLIND_SQL_INSTONE

Làm thế nào để tránh các lỗ hổng tiêm SQL::

  • OWASP Nhà phát triển Hướng dẫn bài viết về cách tránh các lỗ hổng SQL
  • Bảng gian lận của OWASP cung cấp nhiều ví dụ cụ thể về ngôn ngữ về các truy vấn được tham số hóa bằng cả câu lệnh được chuẩn bị và các quy trình được lưu trữ
  • Trang web Bobby Bawabl

Cách xem xét mã cho các lỗ hổng SQL Incent::

  • Hướng dẫn xem xét mã OWASP về cách xem xét mã cho các lỗ hổng SQL

Cách kiểm tra các lỗ hổng tiêm SQL::

  • Hướng dẫn kiểm tra OWASP về cách kiểm tra các lỗ hổng SQL

SQL tiêm trong Java với ví dụ là gì?

SQL Injection thường xảy ra khi bạn yêu cầu người dùng đầu vào, như tên người dùng/userid của họ và thay vì tên/ID, người dùng cung cấp cho bạn câu lệnh SQL mà bạn sẽ vô tình chạy trên cơ sở dữ liệu của mình. Nhìn vào ví dụ sau tạo câu lệnh CHỌN bằng cách thêm một biến [txtuserid] vào một chuỗi chọn.usually occurs when you ask a user for input, like their username/userid, and instead of a name/id, the user gives you an SQL statement that you will unknowingly run on your database. Look at the following example which creates a SELECT statement by adding a variable [txtUserId] to a select string.

Thực hành tốt nhất trong việc bảo vệ chống tiêm SQL là gì?

Các nhà phát triển có thể ngăn chặn các lỗ hổng SQL Incation trong các ứng dụng web bằng cách sử dụng các truy vấn cơ sở dữ liệu được tham số hóa với các tham số được gõ ràng buộc và sử dụng cẩn thận các quy trình được lưu trữ tham số trong cơ sở dữ liệu. Điều này có thể được thực hiện trong một loạt các ngôn ngữ lập trình bao gồm Java,. Net, PHP, và nhiều hơn nữa.utilizing parameterized database queries with bound, typed parameters and careful use of parameterized stored procedures in the database. This can be accomplished in a variety of programming languages including Java, . NET, PHP, and more.

Cuộc tấn công tiêm SQL nào là dễ thực hiện nhất?

SQLI trong băng tần [SQLI cổ điển] tiêm SQL trong băng tần là lần tấn công SQL phổ biến và dễ khai thác nhất. Tiêm SQL trong băng tần xảy ra khi kẻ tấn công có thể sử dụng cùng một kênh truyền thông để cả hai khởi động cuộc tấn công và thu thập kết quả. [Classic SQLi] In-band SQL Injection is the most common and easy-to-exploit of SQL Injection attacks. In-band SQL Injection occurs when an attacker is able to use the same communication channel to both launch the attack and gather results.

Ba cách để giảm thiểu các mối đe dọa tiêm SQL chọn ba là gì?

Làm thế nào để ngăn chặn các cuộc tấn công tiêm SQL vào năm 2022..
Các cuộc tấn công và phát hiện tự áp đặt ..
Xác nhận đầu vào của người dùng ..
Vệ sinh dữ liệu bằng cách giới hạn các ký tự đặc biệt ..
Thực thi các tuyên bố và tham số hóa đã chuẩn bị ..
Sử dụng các thủ tục được lưu trữ trong cơ sở dữ liệu ..
Tích cực quản lý các bản vá và cập nhật ..
Nâng tường lửa ảo hoặc vật lý ..

Bài Viết Liên Quan

Chủ Đề