2009-12-02 32 views
6

Tôi đang cố gắng để đơn giản chứng minh ở đây là chức năng đơn giản này là không đủ tốt để ngăn chặn tất cả các sql injection trên thế giới:minh SQL Injection

Function CleanForSQL(ByVal input As String) As String 
    Return input.Replace("'", "''") 
End Function 

Đây là một tuyên bố chèn điển hình từ một trong những ứng dụng của chúng tôi :

Database.DBUpdate("UPDATE tblFilledForms SET Text1 = '" + CleanForSQL(txtNote.Text) + "' WHERE FilledFormID = " + DGVNotes.SelectedRows(0).Cells("FilledFormID").Value.ToString) 

Tôi biết nó không an toàn, vì googling và tra cứu các câu hỏi khác trên StackOverflow.com. Here là một câu hỏi mà tôi tìm thấy trong đó tất cả các chức năng như tôi đã trình bày ở trên là không liên quan và vô nghĩa.

Vì vậy, dựa trên các bài tôi liên kết với, chỉ cần gõ

'Chr (8); cập nhật tblMaint SET Value1 = 2 ĐÂU ValueID = 2--

vào txtNote nên đủ để xóa tất cả các giá trị trong text1 trong toàn bộ bảng tblFilledForms, và sau đó cập nhật hàng thứ hai bảng tblmaint để được 2 có đúng không?

gì sẽ xảy ra ở đây là VB sẽ giải thích điều này như

tblFilledForms cập nhật bộ Text1 = '' 'Chr (8); cập nhật tblMaint SET Value1 = 2 ĐÂU ValueID = 2-- 'WHERE FilledFormID = 5120327

và gửi cho SQL mà sẽ thực tập thực hiện Chr (8) để xóa thứ ba' mà sẽ tạo ra

CẬP NHẬT tblFilledForms SET Text1 = ''; cập nhật giá trị TblMaint SET Value1 = 2 WHERE ValueID = 2-- 'WHERE FilledFormID = 5120327

để thực sự được thực thi trên cơ sở dữ liệu chính xác?

Tôi sau đó coppied một Chr (8) từ clipboard và thay thế Chr (8) trong hộp văn bản với nội dung clipboard và vẫn không có. Nó đặt toàn bộ chuỗi trực tiếp vào trường w/o vấn đề.

Vì vậy, tôi đang làm gì sai ở đây? hoặc tôi có thể làm gì khác để phá vỡ nó?

Công nghệ và nền: Tôi đang sử dụng MS SQL Server 2005 và VB .NET 2005. trường Text1 trong cơ sở dữ liệu là trường Varchar (600) (không hỏi lý do tại sao không phải MAX, vô nghĩa của nó, tôi biết) Có một số tác nhân nhất định trên bàn có thể ngăn chặn cập nhật hàng loạt như thế này và ném một số lỗi nếu tiêm thực sự hoạt động đúng.

PS. Tôi biết parametrized truy vấn là con đường để đi ở đây và tôi không tìm kiếm câu trả lời như "cũng i dunno lý do tại sao nó không hoạt động, nhưng parametrized truy vấn là con đường để đi". Tôi đang tìm kiếm khả năng chứng minh rằng phần mềm của chúng tôi bị hỏng và chúng tôi cần phải viết lại nó bằng các nguyên tắc tốt hơn.

Đối với bất kỳ ai đọc câu hỏi này để tìm hiểu cách lọc tốt hơn các trường văn bản của bạn, câu trả lời KHÔNG ĐƯỢC! Sử dụng các thông số! chúng tốt hơn, an toàn hơn và dễ dàng hơn!

+5

Lưu ý vì đe doạ mọi người và viết hiệu trưởng thay vì các nguyên tắc trong cùng một đoạn. –

+0

Vâng Chr của bạn (8) kết thúc bên trong một chuỗi vì vậy đó là lý do tại sao SQL không đánh giá nó. –

+6

@Vinko Tôi không nghĩ rằng đó là công bằng, ông chỉ đơn giản là thiết lập một hướng dẫn cho câu trả lời.Vì vậy, thay vì nhận được một loạt các câu trả lời tất cả đều nói cùng một điều, anh ta nhận được 1 hoặc 2 cho anh ta biết anh ta muốn gì. – Zoidberg

Trả lời

6

Chr (8) là một phần của chuỗi ký tự được trích dẫn, như là câu lệnh cập nhật, vì vậy SQL Server sẽ không diễn giải nó như một cuộc gọi hàm. Với ví dụ này, Text1 sẽ được thiết lập để các giá trị văn chương:

'Chr(8); update tblMaint SET Value1 = 2 WHERE ValueID = 2-- 

(vâng, trong đó có trích dẫn đơn)

Như vậy, với ví dụ này, mã của bạn an toàn. Hầu hết treo-vắt qua SQL injection là vô tình không để xác thực và báo giá trị, không có gì vốn không an toàn trong một câu lệnh SQL được trích dẫn đúng.

+0

đã +1 vì câu trả lời của bạn có thể được định hình để trở thành câu trả lời cuối cùng cho câu hỏi này. – Jrud

0

Tôi nghĩ vấn đề của bạn là Chr(8) không được thực hiện, bạn cần phải tìm một cách khác để có được những dấu báo hàng đầu trong.

+0

vâng tôi có ... bất kỳ đề xuất nào không? – Jrud

1

Bạn sẽ không làm điều gì sai trái. Đây là cách SQL Server phân tích chuỗi. Trích dẫn đầu tiên mở chuỗi, sau đó bạn đã theo dõi ngay lập tức với một dấu trích dẫn được theo sau bởi Chr (8).

Làm bài tập, điều gì xảy ra nếu bạn chạy điều này trong SQL Server: SELECT '''Hello'? Chính xác các quy tắc phân tích cú pháp tương tự đang được áp dụng trong trường hợp này.

+0

yep, đó là chính xác những gì đang xảy ra, tôi hiểu. Nhưng tôi vẫn cần phải phá vỡ nó bằng cách nào đó ... – Jrud

+0

Bạn không cần phải phá vỡ nó - bạn chỉ cần chứng minh rằng kỹ thuật của bạn làm việc cho mọi trường hợp, hay không. –

+0

vâng, nếu nó hoạt động cho tất cả các trường hợp, điều đó sẽ loại bỏ loại bỏ bằng cách loại bỏ. – Jrud

4

Phương pháp CleanForSQL của bạn chỉ xử lý các tình huống chuỗi. Điều gì sẽ xảy ra khi bạn không sử dụng chuỗi ký tự thay vì INT? Trong trường hợp đó, sẽ không có dấu kết thúc để đóng, vì vậy việc tiêm vẫn sẽ xảy ra. Hãy xem xét ví dụ này ...

Database.DBUpdate("UPDATE tblFilledForms SET Int1 = " + CleanForSQL(txtNote.Text) + " WHERE FilledFormID = " + DGVNotes.SelectedRows(0).Cells("FilledFormID").Value.ToString) 

trong trường hợp đó, chỉ cần nhập vào đây sẽ làm việc ...

0; update tblMaint SET Value1 = 2 WHERE ValueID = 2--

+0

Chúng tôi không cho phép người dùng nhập bất kỳ số nào vào trường văn bản mà trước tiên không được kiểm tra là số đầu tiên. Tôi chắc chắn điều này sẽ phá vỡ nếu nó là một lĩnh vực số, nhưng chúng tôi không sử dụng phương pháp này cho điều đó. Nó là đúng cho dây. – Jrud

+4

Đừng quên rằng nó có thể là số ID hoặc một cái gì đó trong chuỗi truy vấn - không chỉ là hộp văn bản. Hầu hết các tiêm tôi đã đi qua đã được kiểm tra các biến trong chuỗi truy vấn, và không phải trong các lĩnh vực hình thức. –

+2

+1 vào chuỗi truy vấn - Và đừng quên rằng bất kỳ ai cũng có thể tạo biểu mẫu giả để đăng lên trang của bạn. Tôi không biết làm thế nào DGVNotes.SelectedRows (0) .Cells ("FilledFormID") là nhận được thiết lập, nhưng nếu nó đến từ trình duyệt AT ALL, sau đó SQL có thể được tiêm. Tôi biết bạn luôn kiểm tra các trường số của bạn, nhưng nếu bạn quên, nó sẽ mở một lỗ. –

3

Scott Ivey có trường hợp cổ điển có thể phá vỡ nó, sự thiếu dấu ngoặc kép bảo vệ đầu vào số. (+ 1'ed that)

Tùy thuộc vào ngôn ngữ và nơi chuỗi đang được 'làm sạch' và cơ sở dữ liệu đang được sử dụng rủi ro trực tiếp của bạn là ngôn ngữ cho phép chuỗi được thoát. Vào thời điểm đó, báo giá duy nhất bạn đang cố gắng tránh bị trục xuất sai

\ '; DROP yourTable; - => \ ''; Thả yourTable; -

Mà đi vào chuỗi sql của bạn như

UPDATE tblFilledForms SET Text1 = '" + \''; DROP yourTable;-- + ' etc. 

Đó là sau đó:

UPDATE tblFilledForms SET Text1 = '\''; DROP yourTable;-- ' etc. 

'\'' được thực hiện như là chuỗi đen của một báo duy nhất, nếu cơ sở dữ liệu của bạn hỗ trợ các ký tự thoát - bingo bị xâm phạm.

Tương tự việc bảo vệ phải được nhớ là có hiệu quả, ngay cả câu lệnh cập nhật ví dụ được cung cấp không bảo vệ tham số trong mệnh đề where, là vì DGVNotes.SelectedRows (0) .Cells ("FilledFormID"). ToString) không bao giờ có thể được nhập bởi người dùng? điều đó có đúng với toàn bộ thời gian tồn tại của ứng dụng không?

+0

Có lẽ chỉ là công nghệ DB tôi đang sử dụng ... MS SQL Server thấy \ 'có nghĩa là bạn thực sự muốn gõ \' nó không phải là một ký tự chữ hoặc thoát. Đối với SQL Server, hai dấu nháy đơn cùng nhau được hiểu là một dấu ngoặc kép đơn làm cho bất kỳ '' nào được truyền vào nó một chữ 'bên trong chuỗi và nó sẽ không được thực thi. – Jrud

+0

Có, SQL chỉ thoát khỏi những thứ nhất định và sử dụng [như là thoát, MySQL sử dụng \ Tôi tin rằng để chạy vào vấn đề này. – Andrew

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