SQLParameter ngăn chặn SQL Injection như thế nào?


76

Chính xác thì điều gì đang xảy ra trong nền khiến SQLParameter ngăn chặn các cuộc tấn công SQL Inection trong một truy vấn .NET Parameterized? Nó chỉ là loại bỏ bất kỳ ký tự nghi ngờ nào hoặc có điều gì đó hơn thế?

Có ai ngoài đó đã kiểm tra xem điều gì thực sự đến với SQL Server khi bạn chuyển đầu vào độc hại không?

Liên quan: Bạn có thể sử dụng SQLParameter trong câu lệnh SQL FROM không?

Câu trả lời:


78

Về cơ bản, khi bạn thực hiện SQLCommandsử dụng SQLParameters, các tham số không bao giờ được chèn trực tiếp vào câu lệnh. Thay vào đó, một thủ tục được lưu trữ trong hệ thống được gọi sp_executesqlđược gọi và cung cấp chuỗi SQL và mảng tham số.

Khi được sử dụng như vậy, các tham số được tách biệt và được coi là dữ liệu, thay vì phải được phân tích cú pháp ra khỏi câu lệnh (và do đó có thể thay đổi nó), vì vậy những gì tham số chứa không bao giờ có thể được "thực thi". Bạn sẽ chỉ nhận được một lỗi lớn là giá trị tham số không hợp lệ theo một cách nào đó.


1
Bạn cũng sẽ gặp lỗi khi cố gắng sử dụng biến ở những nơi mà SQL (và TSQL trong trường hợp này) không hỗ trợ biến. IE: FROMmệnh đề, một tham số duy nhất để đại diện cho danh sách được phân tách bằng dấu phẩy trong một INmệnh đề, v.v.
OMG Ponies

1
Tôi không nghĩ điều này trả lời câu hỏi. Bạn có thể gọi một thủ tục được lưu trữ bằng cách sử dụng lớp SQLParameter, lớp này chuyển các tham số cho thủ tục, nhưng không gọi sp_executesql. Điều gì xảy ra với các giá trị tham số trong một chuỗi sql được nối?
Ian

58

Một câu trả lời dễ hiểu hơn và tổng quát hơn như sau:

Hãy tưởng tượng một truy vấn SQL động:

sqlQuery='SELECT * FROM custTable WHERE User=' + Username + ' AND Pass=' + password

Một cách chèn SQL đơn giản sẽ chỉ là đặt Tên người dùng là ' OR 1=1--

Điều này sẽ thực hiện một cách hiệu quả truy vấn SQL:

sqlQuery='SELECT * FROM custTable WHERE User='' OR 1=1-- ' AND PASS=' + password

Điều này cho biết hãy chọn tất cả khách hàng mà tên người dùng của họ trống ( '') hoặc 1=1, là boolean, tương đương với true. Sau đó, nó sử dụng --để nhận xét phần còn lại của truy vấn. Vì vậy, điều này sẽ in ra toàn bộ bảng khách hàng hoặc cho phép bạn làm bất cứ điều gì bạn muốn với nó.

Giờ đây, các truy vấn được tham số hóa làm điều đó theo cách khác, với mã như:

sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?' parameters.add("User", username) parameters.add("Pass", password)

trong đó tên người dùng và mật khẩu là các biến trỏ đến tên người dùng và mật khẩu được nhập được liên kết.

Bây giờ tại thời điểm này, bạn có thể nghĩ rằng, điều này không thay đổi bất cứ điều gì cả. Chắc chắn bạn vẫn có thể đặt vào trường tên người dùng một cái gì đó như Không ai HOẶC 1 = 1 '-, thực hiện truy vấn một cách hiệu quả:

sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND Pass=?'

Và điều này có vẻ như là một lập luận hợp lệ. Nhưng bạn có thể đã sai.

Cách hoạt động của các truy vấn được tham số hóa, đó là truy vấn SQL được gửi dưới dạng một truy vấn và cơ sở dữ liệu biết chính xác truy vấn này sẽ làm gì và chỉ sau đó nó mới chèn tên người dùng và mật khẩu đơn thuần dưới dạng giá trị. Điều này có nghĩa là chúng không thể ảnh hưởng đến truy vấn, vì cơ sở dữ liệu đã biết truy vấn sẽ làm gì. Vì vậy, trong trường hợp này, nó sẽ tìm kiếm tên người dùng Nobody OR 1=1'--và một mật khẩu trống, điều này sẽ dẫn đến sai.

Tuy nhiên, đây không phải là một giải pháp hoàn chỉnh và vẫn cần phải thực hiện xác thực đầu vào vì điều này sẽ không ảnh hưởng đến các vấn đề khác, chẳng hạn như tấn công, vì bạn vẫn có thể đưa javascript vào cơ sở dữ liệu. Sau đó, nếu điều này được đọc ra trên một trang, nó sẽ hiển thị dưới dạng javascript bình thường, tùy thuộc vào bất kỳ xác nhận đầu ra nào. Vì vậy, thực sự điều tốt nhất cần làm vẫn là sử dụng xác nhận đầu vào, nhưng sử dụng truy vấn được tham số hóa hoặc các thủ tục được lưu trữ để ngăn chặn bất kỳ cuộc tấn công SQL nào.

Nguồn: http://www.lavamunky.com/2011/11/why-parameterized-queries-stop-sql.html


10

"Bộ sưu tập tham số như SqlParameterCollection cung cấp tính năng kiểm tra kiểu và xác thực độ dài. Nếu bạn sử dụng bộ sưu tập tham số, đầu vào được coi là giá trị chữ và SQL Server không coi nó là mã thực thi. Một lợi ích bổ sung của việc sử dụng bộ sưu tập tham số là bạn có thể thực thi kiểm tra loại và độ dài. Các giá trị nằm ngoài phạm vi kích hoạt ngoại lệ. Đây là một ví dụ điển hình về bảo vệ theo chiều sâu. "

http://msdn.microsoft.com/en-us/library/ff648339.aspx


5

Khi sử dụng các truy vấn được tham số hóa, bề mặt tấn công được giảm xuống mức độ xung quanh của các tham số.

Hãy sử dụng SqlParameters, nhưng đừng quên các thông số tràn, dòng dưới và chưa được kiểm chứng. Ví dụ: nếu phương thức là "proc buy_book (@price money)", kẻ tấn công độc hại sẽ cố gắng lừa ứng dụng chạy với @priceset to 0.01hoặc cố gắng khiến ứng dụng thực hiện điều gì đó thú vị bằng cách gửi thứ gì đó gây tràn. Sql Overflows có xu hướng không thú vị (tức là chúng chỉ gây ra các ngoại lệ, bạn không thể ghi vào bộ nhớ liền kề)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.