2014-12-02 12 views
5

Tôi hoàn toàn nhận thức được rằng thực hành chính xác để vệ sinh các truy vấn SQL là tham số hóa chúng.T-SQL an toàn như thế nào sau khi bạn thay thế 'ký tự thoát?

Tôi làm việc trên rất nhiều mã đã tồn tại từ trước, trong đó biện pháp vệ sinh là thay thế tất cả các trường hợp ' bằng '' trong chuỗi động. Tôi đang cố gắng tìm ra mối quan tâm của tôi.

Đây là điều: mã này chạy độc quyền trên T-SQL (SQL Server 2008R2 và cao hơn) và, như xa như tôi có thể nói, ' là các ký tự thoát chỉ cho T-SQL.

Vì vậy, làm thế nào bạn sẽ thực hiện một cuộc tấn công tiêm để vượt qua các biện pháp trên? I E. đó là sự khử trùng rất "ngây thơ" thực sự khá vững chắc trên T-SQL, vì nó trông như thế nào?

+3

Người ta có thể thay thế các nhân vật báo duy nhất với đại diện thập lục phân của nó, hoặc đại diện Unicode của nó, hoặc một thực thể lừa "vệ sinh" của bạn bằng cách dự đoán hành vi đó và sử dụng số hợp lý dấu nháy đơn để "vệ sinh" của bạn hoàn toàn thất bại .... ** nghiêm túc **: không làm điều này. *** KHÔNG BAO GIỜ BAO GIỜ *** - sử dụng parmaeters - *** LUÔN LUÔN *** –

+1

@marc_s Hãy viết một câu lệnh chèn chèn 1000 dòng với 50 trường. Nếu bạn có thể làm điều đó (gợi ý: bạn có thể không) sau đó tôi gọi đó là một bình luận tốt. Nếu không thì: dốt nát. Số lượng tham số bị giới hạn và có những trường hợp tốt để sử dụng một cách tiếp cận khác, đôi khi. – TomTom

+2

Nếu bạn đang làm điều đó TomTom sử dụng SQLBulkCopy - marc_s là đúng, ít nhất là liên quan đến việc sử dụng các thông số – Swomble

Trả lời

3

Có, một trích dẫn là ký tự thoát duy nhất để bạn là chủ yếu là, nhưng không hoàn toàn ok.

Sử dụng thông số, trong khi tốt nhất, chủ yếu chỉ thực hiện thay thế ' thành '' mà bạn đang thực hiện thủ công. NHƯNG, họ cũng thực thi độ dài chuỗi tối đa. Tất nhiên, nếu chúng ta đang nói về các tham số không phải chuỗi, chúng sẽ có lợi ích của việc thực thi kiểu dữ liệu (ví dụ: ' không cần phải được thoát cho các kiểu số, ngày/giờ, vv vì nó không hợp lệ cho bắt đầu bằng).

Sự cố bạn vẫn có thể bị bỏ qua là một tập con của SQL Injection được gọi là Cắt ngắn SQL. Ý tưởng là để buộc một số phần của sql động ra khỏi cuối chuỗi. Tôi không chắc chắn khả năng điều này xảy ra trong thực tế, nhưng, tùy thuộc vào cách thức và nơi bạn đang xây dựng sql động, bạn cần đảm bảo rằng biến giữ SQL động để thực thi đủ lớn để giữ các phần tử tĩnh trong mã của bạn cộng với tất cả các biến giả sử chúng được gửi ở độ dài tối đa của chúng.

Đây là một bài viết từ Tạp chí MSDN, New SQL Truncation Attacks And How To Avoid Them, hiển thị cả SQL Injection thông thường lẫn SQL Truncation. Bạn sẽ thấy trong bài viết để tránh SQL Injection họ chủ yếu chỉ làm phương thức REPLACE(@variable, '''', ''''''), nhưng cũng hiển thị sử dụng QUOTENAME(@variable, '[') cho một số trường hợp.

EDIT (2015/01/20): Dưới đây là một nguồn lực tốt, mặc dù không cụ thể cho SQL Server, mà chi tiết nhiều loại hình SQL Injection: https://www.owasp.org/index.php/Testing_for_SQL_Injection_(OTG-INPVAL-005)

Bài viết sau đây có liên quan đến một ở trên . Đây là một trong những cụ thể cho SQL Server, nhưng tổng quát hơn về an ninh tổng thể. Có phần liên quan đến SQL Injection:
https://www.owasp.org/index.php/Testing_for_SQL_Server

+0

Cảm ơn bạn! Chính xác loại câu trả lời tôi đang tìm kiếm. – piaste

3

(Chèn biểu về nguy hiểm của sanitization bị phá vỡ và thoát ở đây. Xem bình luận của marc_s.)

gì bạn đề xuất ở đây là phương pháp tương tự mà Microsoft SQL Server Managed Objects (SMO) sử dụng. Đó là các DLL .NET mà người ta có thể kiểm tra bằng cách sử dụng một trình dịch ngược. Ví dụ:

internal static string MakeSqlString(string value) 
{ 
    StringBuilder builder = new StringBuilder(); 
    builder.Append("N'"); 
    builder.Append(EscapeString(value, '\'')); 
    builder.Append("'"); 
    return builder.ToString(); 
} 

public static string EscapeString(string value, char escapeCharacter) 
{ 
    StringBuilder builder = new StringBuilder(); 
    foreach (char ch in value) 
    { 
     builder.Append(ch); 
     if (escapeCharacter == ch) 
     { 
      builder.Append(ch); 
     } 
    } 
    return builder.ToString(); 
} 

Vì vậy, có, chỉ cần thực hiện Replace("'", "''") là đủ theo Microsoft. Tôi chắc rằng đây không chỉ là mã thực tập nhưng đã được kiểm tra về bảo mật. Họ luôn làm điều này do SDL.

Cũng lưu ý rằng mã này dường như được thực hiện để hoạt động với Unicode (xem tiền tố N). Rõ ràng, điều này cũng an toàn với Unicode.

Ghi chú chủ quan hơn: Tôi thoát khỏi chuỗi chữ T-SQL giống như thế này nếu tôi phải làm như vậy. Tôi tin tưởng phương pháp này.

2

Đây là trong .NET
bây giờ tôi nhận thấy các câu hỏi được gắn thẻ TSQL nhưng không NET

Marc ngụ ý bạn có thể đánh lừa nó với unicode hoặc hex đại diện. Tôi đã thử nghiệm và không có unicode cũng không hex lừa nó trong.

Để đánh lừa nó với số lượng dấu nháy đơn phù hợp. Nếu bạn luôn luôn thay thế một với hai tôi không thấy làm thế nào một số thích hợp có thể đánh lừa nó.

u0027 và x0027 là dấu nháy đơn và nó được thay thế bằng hai dấu nháy đơn
năm 2018 và 2019 còn lại và báo giá ngay và SQL chỉ đối xử với họ như literals

string badString = "sql inject \' bad stuff here hex \x0027 other bad stuff unicode \u0027 other bad stuff left \u2018 other bad stuff right \u2019 other bad stuff"; 
    System.Diagnostics.Debug.WriteLine(badString); 
    System.Diagnostics.Debug.WriteLine(SQLclean(badString)); 
} 
public string SQLclean(string s) 
{ 
    string cleanString = s.Replace("\'", "\'\'"); 
    return "N\'" + cleanString + "\'"; 
} 

Tôi nghĩ rằng các thông số là một thực hành tốt hơn

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