2010-08-27 30 views
6

Tôi là một nhà phát triển máy tính để bàn viết cho người dùng nội bộ, vì vậy tôi không lo lắng về tin tặc độc hại, nhưng tôi muốn biết nếu có bất cứ điều gì họ có thể nhập khi cập nhật một giá trị sẽ thực thi sql trên máy chủ.Người dùng của tôi có thể tiêm sql động của tôi không?

Doanh nghiệp xác định lược đồ nội dung của họ và tôi có một ứng dụng CRUD cho họ không cần phải thay đổi khi thay đổi lược đồ của họ vì chi tiết xác thực được định hướng theo bảng và cập nhật bằng SQL động. Tôi phải hỗ trợ dấu nháy đơn trong mục nhập dữ liệu của họ, vì vậy khi họ nhập chúng, tôi tăng gấp đôi chúng trước khi SQL được thực thi trên máy chủ. Từ những gì tôi đã đọc, tuy nhiên, điều này không đủ để ngăn chặn tiêm.

Vì vậy, câu hỏi của tôi là, văn bản nào họ có thể nhập vào trường văn bản dạng tự do có thể thay đổi thứ gì đó trên máy chủ thay vì được lưu trữ dưới dạng giá trị bằng chữ?

Về cơ bản, tôi đang xây dựng một câu lệnh SQL trong thời gian chạy mà theo mẫu:

cập nhật bảng thiết lập trường = giá trị nơi pkField = pkVal

với mã này VB.NET:

Friend Function updateVal(ByVal newVal As String) As Integer 
    Dim params As Collection 
    Dim SQL As String 
    Dim ret As Integer 

    SQL = _updateSQL(newVal) 
    params = New Collection 
    params.Add(SQLClientAccess.instance.sqlParam("@SQL", DbType.String, 0, SQL)) 
    Try 
     ret = SQLClientAccess.instance.execSP("usp_execSQL", params) 
    Catch ex As Exception 
     Throw New Exception(ex.Message) 
    End Try 
    Return ret 
End Function 

Private Function _updateSQL(ByVal newVal As String) As String 
    Dim SQL As String 
    Dim useDelimiter As Boolean = (_formatType = DisplaySet.formatTypes.text) 
    Dim position As Integer = InStr(newVal, "'") 
    Do Until position = 0 
     newVal = Left(newVal, position) + Mid(newVal, position)  ' double embedded single quotes ' 
     position = InStr(position + 2, newVal, "'") 
    Loop 
    If _formatType = DisplaySet.formatTypes.memo Then 
     SQL = "declare @ptrval binary(16)" 
     SQL = SQL & " select @ptrval = textptr(" & _fieldName & ")" 
     SQL = SQL & " from " & _updateTableName & _PKWhereClauses 
     SQL = SQL & " updatetext " & _updateTableName & "." & _fieldName & " @ptrval 0 null '" & newVal & "'" 
    Else 
     SQL = "Update " & _updateTableName & " set " & _fieldName & " = " 
     If useDelimiter Then 
      SQL = SQL & "'" 
     End If 
     SQL = SQL & newVal 
     If useDelimiter Then 
      SQL = SQL & "'" 
     End If 
     SQL = SQL & _PKWhereClauses 
    End If 
    Return SQL 
End Function 

khi tôi cập nhật trường văn bản thành giá trị

Redmond '; thả bảng OrdersTable--

nó tạo ra:

Update caseFile set notes = 'Redmond''; drop table OrdersTable--' where guardianshipID = '001168-3' 

và cập nhật các giá trị cho các giá trị văn chương họ đã nhập.

Họ có thể nhập mã SQL nào khác?

Một lần nữa, tôi không lo lắng ai đó muốn hack máy chủ trong công việc của họ, nhưng muốn biết làm thế nào nếu họ có thể vô tình dán văn bản từ một nơi khác và phá vỡ một cái gì đó.

Cảm ơn.

+4

"Tôi không lo lắng ai đó muốn tấn công máy chủ tại nơi làm việc của họ" - bạn tốt hơn, nhân viên bất bình làm những kẻ tấn công khá khó chịu. –

+4

Nếu bạn là một, bạn sẽ sử dụng sql nào? – Beth

+1

+1 Để có câu hỏi hay. Đây là điều tôi đã tự hỏi về bản thân mình. Tôi đã nhìn thấy rất nhiều xác nhận mơ hồ trong sách giáo khoa về điều này là không đủ nhưng không bao giờ giải thích tại sao. Tôi sẽ rất vui nếu có ai đó có thể trả lời đúng với một ví dụ dứt khoát về đầu vào của người dùng có thể gây ra vấn đề. Tôi sẵn sàng đặt cược bây giờ rằng điều này sẽ không xảy ra mặc dù và hoàn thành câu trả lời không ** mà không giải quyết các câu hỏi rất cụ thể ** giới thiệu SQL parameterised sẽ được bình chọn lên hàng đầu. –

Trả lời

1

Giả sử bạn thoát khỏi chuỗi ký tự (từ những gì bạn nói bạn đang làm), bạn nên an toàn. Điều duy nhất tôi có thể nghĩ là nếu bạn sử dụng một ký tự unicode dựa trên thiết lập để giao tiếp với cơ sở dữ liệu, hãy chắc chắn rằng các chuỗi bạn gửi là hợp lệ trong mã hóa đó.

+0

bạn có thể cho tôi ví dụ về chuỗi không hợp lệ mà tôi có thể thử dán vào hộp văn bản của mình không? – Beth

+0

Nếu tôi cố gắng đăng chuỗi không hợp lệ tại đây, nó có trách nhiệm được sửa chữa bởi trang web sao cho UTF-8 không hợp lệ không được lưu trữ trong cơ sở dữ liệu của StackOverflow.Vì vậy, tôi có thể cung cấp cho bạn một công thức cho một chuỗi không hợp lệ, nhưng tôi thực sự không thể đăng một chuỗi. Có nhiều cách trong đó một chuỗi các byte có thể không hợp lệ UTF-8; xem the wikipedia page. Ví dụ, một giá trị byte 254 hoặc 255 không thể xuất hiện trong UTF-8 hợp lệ. – Hammerite

+0

Các lỗi mã hóa mà bạn có thể quan tâm nhất là mã hóa quá mức các ký tự ASCII, chẳng hạn như chuỗi byte (192, 166) (là mã hóa quá dài của một dấu nháy đơn). – Hammerite

1

Vì xấu khi mã tăng gấp đôi của bạn là (: p - Hãy thử String.Replace thay thế.) Tôi chắc chắn rằng sẽ thực hiện công việc.

+1

có, nó hoạt động tốt. Tôi tiếp tục nghe như thế nào bạn sẽ không bao giờ, bao giờ, bao giờ sử dụng sql năng động và muốn hiểu rõ hơn lý do tại sao, nếu tôi xử lý các trường hợp rõ ràng. Tôi đã đọc rằng chỉ cần xử lý trường hợp này là không đủ, nhưng không nhìn thấy ví dụ cho thấy lý do tại sao. – Beth

1

Các chỉ an toàn giả định là nếu bạn không sử dụng các truy vấn tham số (và bạn không, độc quyền, ở đây, bởi vì bạn đang concatenating chuỗi đầu vào sql của bạn), sau đó bạn không an toàn .

+4

Điều này không trả lời được câu hỏi. Đó là lý do tại sao nó không an toàn? Bạn có thể chứng minh điều này? –

+0

ok, vậy văn bản nào họ có thể nhập sẽ ảnh hưởng đến máy chủ? – Beth

+2

Xem http://stackoverflow.com/questions/139199/can-i-protect-against-sql-injection-by-escaping-single-quote-and-surrounding-user cho các trường hợp lý thuyết. Tôi đã không nói rằng bạn không được bảo vệ, tôi chỉ nói giả định * SAFE * duy nhất là bạn chỉ an toàn nếu bạn đang sử dụng các truy vấn được tham số cho TẤT CẢ dữ liệu đến từ người dùng. – Mark

2

Bất kể cách bạn làm sạch đầu vào của người dùng làm tăng bề mặt tấn công là vấn đề thực sự với những gì bạn đang làm. Nếu bạn nhìn lại lịch sử của SQL Injection, bạn sẽ nhận thấy rằng những cách mới và thậm chí còn sáng tạo hơn để tàn phá qua chúng đã xuất hiện theo thời gian. Mặc dù bạn có thể tránh được cái đã biết, nó luôn là những gì ẩn nấp quanh góc khiến cho loại mã này khó sản xuất. Bạn sẽ tốt hơn nếu chỉ sử dụng một cách tiếp cận khác.

+0

Tôi hiểu một ứng dụng web có cập nhật cho thế giới, điều này có ý nghĩa, nhưng điều chính mà người dùng của tôi muốn là có ứng dụng tùy chỉnh mà họ cần xem và sửa đổi dữ liệu của họ, sql động nào cho phép tôi thực hiện mà không thay đổi mã khi lược đồ db của họ thay đổi. – Beth

+0

Tôi hiểu. Một vấn đề khác với SQL động là việc tiêm các ký tự gây ra các tác dụng phụ. Truy vấn tham số hoặc tận dụng LINQ to SQL/Entity Framework chỉ làm cho truy cập dữ liệu của bạn không bị lỗi. –

1

Bạn sẽ không bao giờ bao giờ muốn xây dựng một câu lệnh SQL bằng cách sử dụng đầu vào của người dùng mà sau đó sẽ được thực thi trực tiếp. Điều này dẫn đến các cuộc tấn công SQL injection, như bạn đã tìm thấy. Nó sẽ là tầm thường cho một ai đó để thả một bảng trong cơ sở dữ liệu của bạn, như bạn đã mô tả.

Bạn muốn sử dụng truy vấn được tham số hóa, trong đó bạn tạo chuỗi SQL sử dụng trình giữ chỗ cho giá trị, sau đó chuyển giá trị vào cho các tham số đó.

Sử dụng VB bạn muốn làm điều gì đó như:

'Define our sql query' 
Dim sSQL As String = "SELECT FirstName, LastName, Title " & _ 
        "FROM Employees " & _ 
        "WHERE ((EmployeeID > ? AND HireDate > ?) AND Country = ?)" 

'Populate Command Object' 
Dim oCmd As New OledbCommand(sSQL, oCnn) 

'Add up the parameter, associated it with its value' 
oCmd.Parameters.Add("EmployeeID", sEmpId) 
oCmd.Parameters.Add("HireDate", sHireDate) 
oCmd.Parameters.Add("Country", sCountry) 

(ví dụ lấy từ here) (cũng không Tôi không phải là một lập trình viên VB vì vậy đây có thể không phải cú pháp thích hợp, nhưng nó được điểm qua)

+2

@canspice - Tôi không nghĩ bạn đọc câu hỏi đúng cách. Nó không phải là tầm thường bởi vì bằng cách thoát khỏi báo giá duy nhất những gì được gửi nên được coi là dữ liệu. –

+2

Thực ra, tôi đang cố gắng tìm ra đòn tấn công. SQL trong câu hỏi không gây ra một câu hỏi. Bạn có thể sản xuất sql không? – Beth

+0

Như tôi đã nói, tôi không phải là một lập trình VB. '_formatType = DisplaySet.formatTypes.text' làm gì? Liệu nó chỉ thiết lập 'useDelimiter' nếu đầu vào là văn bản? Tôi đoán những gì tôi hỏi là "làm thế nào để' useDelimiter' được đặt thành false? " – CanSpice

2

Bạn cũng có thể đánh giá giải pháp thay thế. Tạo động của SQL với các tham số. Một cái gì đó như thế này:

// snippet just for get the idea 
var parameters = new Dictionary<string, object>(); 
GetParametersFromUI(parameters); 


if (parameters.ContainsKey("@id")) { 
    whereBuilder.Append(" AND id = @id"); 
    cmd.Parameters.AddWithValue("@id", parameters["@id"]); 
} 
... 
+0

Tôi biết giá trị PK vì họ đã chọn hàng và cột để chỉnh sửa, vì vậy, chỉ giá trị mà họ muốn cập nhật được chuyển trực tiếp đến máy chủ. – Beth

+0

Lý do tôi không làm điều này là bởi vì tôi muốn có cách tiếp cận chung để cập nhật nội dung kinh doanh. Tôi có thể sử dụng cùng mã này cho bất kỳ cập nhật nào trên bất kỳ trường nào trong bất kỳ dự án nào. Giới thiệu các phần tử tĩnh có nghĩa là thay đổi/biên dịch/thử nghiệm/triển khai mã cập nhật, mà tôi muốn tránh nếu tất cả những gì chúng làm là thay đổi lược đồ nội dung hoặc các quy tắc xác thực của chúng. – Beth

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