2009-03-25 41 views
25

Tôi đã tạo một trang web khảo sát nhỏ trên mạng Intranet của công ty chúng tôi. Trang web này không thể truy cập từ bên ngoài.SQL injection trên INSERT

Biểu mẫu chỉ đơn giản là một vài nút radio và hộp nhận xét.

Tôi muốn duy trì các phương pháp mã hóa tốt và muốn bảo vệ chống lại SQL Injection.

Việc chèn SQL có thể xảy ra trên câu lệnh chèn với nhận xét từ hộp văn bản không? Nếu vậy, làm thế nào tôi có thể bảo vệ chống lại nó bằng cách sử dụng .NET 2.0?

+0

Thông tin bổ sung: Khi bạn tạo trang web, không chỉ tập trung vào việc chèn sql. Kiểm tra cũng là nguy cơ XSS của văn bản trước khi bạn chèn nó vào cơ sở dữ liệu của bạn. Mỗi mã đầu ra có được bảo đảm thông qua Server.HtmlEncode (...) không? –

Trả lời

54

Tiêm có thể xảy ra trên bất kỳ câu lệnh SQL nào không chạy đúng cách.

Ví dụ: giả sử bảng nhận xét của bạn có hai trường, một số nguyên ID và chuỗi nhận xét. Vì vậy, bạn muốn INSERT như sau:

INSERT INTO COMMENTS VALUES(122,'I like this website'); 

Hãy xem xét một ai đó bước vào những nhận xét sau đây:

'); DELETE FROM users; -- 

Nếu bạn chỉ cần đặt chuỗi bình luận vào SQL mà không cần bất kỳ processesing này có thể biến đơn INSERT của bạn vào hai câu sau đây theo sau một nhận xét:

INSERT INTO COMMENTS VALUES(123,''); DELETE FROM users; -- '); 

Thao tác này sẽ xóa mọi thứ khỏi bảng users của bạn. Và có những người sẵn sàng dành cả ngày để tìm đúng tablename để trống bằng cách dùng thử và lỗi và các thủ đoạn khác nhau. Here's a description of how you could perform an SQL Injection attack.

Bạn cần sử dụng parameterized SQL statements để ngăn điều này.

Và đây không chỉ vì lý do bảo mật. Ví dụ, nếu bạn đang tạo câu lệnh SQL của bạn ngây thơ những nhận xét sau đây:

I'm just loving this website 

sẽ gây ra lỗi cú pháp SQL vì dấu nháy đơn được giải thích bởi SQL như một báo bế mạc.

+2

điểm tốt đẹp trên dấu nháy đơn - Tôi đã sử dụng phương pháp string.replace - nhưng tôi có thể thấy điều này dễ dàng hơn nhiều. – Brad

+0

Rất tốt giải thích. Thực hiện tốt. –

+1

Ngay cả một tên sẽ gây ra một vấn đề nếu không được thực hiện như một tham số, ví dụ như O'Tool, O'Rourke. – Martin

27

Sử dụng truy vấn được tham số hóa để văn bản tự động được trích dẫn cho bạn.

SqlCommand command = connection.CreateCommand(); 
command.CommandText = "insert into dbo.Table (val1,val2,txt) values (@val1,@val2,@txt)"; 
command.AddParameterWithValue("val1", value1); 
command.AddParameterWithValue("val2", value2); 
command.AddParameterWithValue("txt", text); 

... 
-4

Cách dễ nhất để bảo vệ chống lại dạng SQL injection đó, là sử dụng các tham số và các thủ tục được lưu trữ thay vì xây dựng các câu lệnh sql để chạy. (Trong C# hoặc nội bộ đến SQL Server). Tuy nhiên, tôi không hoàn toàn chắc chắn bạn nên dành thời gian cho việc này, trừ phi đó là chính sách của công ty bạn, vì cơ hội xảy ra trong nội bộ tối thiểu là tốt nhất, và nếu điều đó xảy ra, tôi hy vọng bạn sẽ biết ngay đó là ai.

+0

Tất nhiên, một nhân viên bất mãn sẽ không bao giờ cố gắng tìm kiếm cơ sở dữ liệu của công ty bạn. Bạn luôn cần phải lo lắng về bảo mật và thực hiện theo các phương pháp hay nhất. – tvanfosson

+0

Tôi không đồng ý. Đây là trang web nội bộ, mà bất kỳ nhân viên cũ nào cũng không thể truy cập được. Ngoài ra tôi sẽ đoán (hoặc chắc chắn hy vọng), rằng tất cả lưu lượng truy cập nội bộ được ghi lại. Nhu cầu bảo mật, phải được đánh giá cùng với các critiera khác và có thể không được biện minh trong một số trường hợp. – Bravax

+0

Ai nói rằng bạn phải là một nhân viên cũ bị bất mãn? An ninh tốt là ngăn chặn thiệt hại, không gán đổ lỗi sau đó. Trong trường hợp này, chi phí sử dụng các truy vấn được tham số hóa không cao lắm. Nó phải là tiêu chuẩn khi xây dựng các truy vấn bằng tay. – tvanfosson

0

Có, nó có thể.Hãy nói rằng khách hàng sẽ gửi này:

OR 1 = 1 

Đó có thể rất painfull cho bạn

SELECT * FROM admin WHERE name = @name AND password = @password 

Bạn có thể ngăn chặn điều này với

+0

Câu hỏi rõ ràng về các câu lệnh INSERT. –

+0

đúng. nhưng có lẽ danh sách sẽ giúp – boj

0

Có, chúng có thể xảy ra. Cách dễ nhất để bảo vệ chống lại điều này là sử dụng các câu lệnh đã được chuẩn bị hơn là xây dựng SQL theo cách thủ công.

Vì vậy, chứ không phải là điều này:

String sql = 
String.Format("INSERT INTO mytable (text_column) VALUES ('{0}')", 
    myTextBox.Text); // Unsafe! 

Bạn sẽ làm một cái gì đó như thế này:

String sql = "INSERT INTO mytable (text_column) VALUES (?)"; // Much safer 

Sau đó, thêm văn bản của hộp văn bản như một tham số để DbCommand của bạn mà sẽ gây ra nó để được tự động thoát và thay thế "?" trong SQL.

0

Ngoài việc sử dụng chuẩn bị phát biểu và các thông số chứ không phải là concatenating dây vào SQL của bạn, bạn cũng nên làm như sau:

  1. Validate và người sử dụng định dạng đầu vào ở phía máy chủ. Xác thực và giới hạn bên ứng dụng khách có thể dễ dàng bỏ qua bằng các công cụ như WebScarab hoặc bằng cách giả mạo biểu mẫu của bạn.

  2. Định cấu hình quyền thích hợp cho tài khoản người dùng cơ sở dữ liệu. Ứng dụng web nên sử dụng một tài khoản hoặc vai trò riêng trong cơ sở dữ liệu của bạn với các quyền hạn chế chỉ với các bảng, các khung nhìn và các thủ tục cần thiết để chạy ứng dụng của bạn. Đảm bảo rằng người dùng không có quyền chọn trên bảng hệ thống

  3. Ẩn thông báo lỗi chi tiết từ người dùng và sử dụng tên ít phổ biến hơn cho đối tượng của bạn. Nó làm tôi ngạc nhiên khi bạn có thể xác định loại máy chủ (oracle, mysql, sqlserver) và tìm thông tin lược đồ cơ bản trong một thông báo lỗi và sau đó lấy thông tin từ các bảng được gọi là 'user (s)', 'employee (s)'. Nếu bạn chưa thiết lập quyền của bạn như trong (2) và tôi có thể xác định loại máy chủ của bạn, bạn đang mở cửa cho báo cáo như thế này cho SQL Server

    CHỌN tên_bảng TỪ information_schema.table

    EXECUTE sp_help foundTableName

3

Chèn SQL có thể xảy ra bất cứ khi nào bạn chuyển truy vấn trở lại cơ sở dữ liệu. Dưới đây là một cuộc biểu tình đơn giản:

SQL Injection Explained

Mấu chốt, trong .NET, là để làm như Dave Webb đã đưa ra. Nó sẽ ngăn chặn các nỗ lực tiêm bằng cách bao gồm toàn bộ chuỗi như một tham số được gửi, xử lý tất cả các ký tự có thể được SQL Server giải thích để thay đổi truy vấn hoặc nối thêm các lệnh bổ sung.

Và cần phải chỉ ra rằng việc chèn SQL có thể xảy ra trên bất kỳ ứng dụng nào, không chỉ các ứng dụng web. Và đó là một cuộc tấn công nội bộ thường là tốn kém nhất cho một tổ chức. Người ta không thể giả định một cách an toàn rằng một cuộc tấn công sẽ không bắt nguồn từ bên trong.

0

Ngăn SQL Injection bằng cách sử dụng câu lệnh đã chuẩn bị. Việc sử dụng các placehoder (?) Hoàn toàn loại bỏ sql Injection Vulnerability. ví dụ Chuỗi sql = Chọn * từ user_table trong đó username = '+ request.getparameter ("username") +'; statement.executeQuery (sql);

tuyên bố ở trên là dễ bị tổn thương với tiêm sql.

Để đảm bảo an toàn khi tiêm sql. Sử dụng sau đoạn mã

Chuỗi sql = Chọn * từ user_table trong đó username = ?; statement.setString (1, tên người dùng);

+0

Cú pháp '?' không hoạt động đối với tất cả các nhà cung cấp/DB. –