2009-08-31 37 views
11

tôi đã xây dựng một truy vấn T-SQL như thế này:Lo ngại về SQL Server 2008 Full Text Search

DECLARE @search nvarchar(1000) = 'FORMSOF(INFLECTIONAL,hills) AND FORMSOF(INFLECTIONAL,print) AND FORMSOF(INFLECTIONAL,emergency)' 

SELECT * FROM Tickets 
WHERE ID IN (
       -- unioned subqueries using CONTAINSTABLE 
          ... 
      ) 

GUI cho tìm kiếm này sẽ là một trang aspx với một hộp duy nhất, nơi người dùng có thể tìm kiếm.

Tôi định xây dựng cụm từ tìm kiếm bằng cách nào đó giống như ví dụ trên (@search).

Tôi có một số mối quan tâm, mặc dù:

  • Là thuật ngữ tìm kiếm ví dụ trên là cách tốt nhất hoặc duy nhất để bao gồm các biến tố của tất cả các từ trong tìm kiếm?
  • Tôi có nên tách các từ và xây dựng cụm từ tìm kiếm trong C# hoặc T-SQL hay không. Tôi có xu hướng nghiêng về phía C# cho các quyết định/looping/xây dựng, nhưng tôi muốn ý kiến ​​của bạn.
  • Tôi ghét xây dựng SQL động vì nguy cơ bị tiêm. Làm thế nào tôi có thể bảo vệ chống lại điều này?
  • Tôi có nên sử dụng FREETEXTTABLE thay thế không? Có cách nào để làm cho FREETEXT tìm kiếm TẤT CẢ các từ thay vì BẤT K??
  • Nói chung, bạn sẽ làm điều này như thế nào?

Trả lời

3

Gần đây, tôi đã sử dụng Tìm kiếm toàn văn bản, vì vậy tôi sẽ cố gắng trả lời một số câu hỏi của bạn.

• "Tôi ghét xây dựng sql động vì nguy cơ bị tiêm. Làm thế nào tôi có thể bảo vệ chống lại điều này?"

tôi đã sử dụng một phương pháp Sanitize như thế này:

static string SanitizeInput(string searchPhrase) 
    { 
     if (searchPhrase.Length > 200) 
      searchPhrase = searchPhrase.Substring(0, 200); 

     searchPhrase = searchPhrase.Replace(";", " "); 
     searchPhrase = searchPhrase.Replace("'", " "); 
     searchPhrase = searchPhrase.Replace("--", " "); 
     searchPhrase = searchPhrase.Replace("/*", " "); 
     searchPhrase = searchPhrase.Replace("*/", " "); 
     searchPhrase = searchPhrase.Replace("xp_", " "); 

     return searchPhrase; 
    } 

• Tôi có nên sử dụng FREETEXTTABLE để thay thế? Có cách nào để làm cho FREETEXT tìm kiếm TẤT CẢ các từ thay vì BẤT K??

Tôi đã sử dụng FREETEXTTABLE, nhưng tôi cần bất kỳ từ nào. Nhiều như tôi đã đọc về nó (và tôi đã đọc khá một chút), bạn phải sử dụng CONTAINSTABLE để tìm kiếm TẤT CẢ các từ hoặc các kết hợp khác nhau. FREETEXTTABLE có vẻ là giải pháp nhẹ hơn, nhưng không phải là giải pháp để chọn khi bạn muốn tùy chỉnh sâu hơn.

0

Trong ví dụ của bạn, bạn có biến số @search đã được xác định. Theo quy tắc chung, bạn không nên bao gồm văn bản được ghép nối động vào SQL thô, do nguy cơ bị tiêm. Tuy nhiên, bạn có thể đặt giá trị của @search trong đối tượng lệnh gọi từ ứng dụng của bạn. Điều này hoàn toàn phủ nhận nguy cơ của các cuộc tấn công tiêm.

Tôi khuyên bạn nên xây dựng cụm từ tìm kiếm trong C#; chuyển cụm từ tìm kiếm cuối cùng dưới dạng tham số như đã đề cập.

Theo như tôi nhớ lại, FREETEXTTABLE sử dụng trình ngắt từ để phân tích hoàn toàn cụm từ tìm kiếm thành các thành phần riêng lẻ của chúng. Tuy nhiên, toán tử FREETEXTTABLE cũng tự động phân tách các từ thành các từ tương đương cũng vậy, vì vậy bạn sẽ không phải xây dựng toán tử phức tạp CONTAINSTABLE nếu bạn quyết định sử dụng nó.

Bạn có thể INNER JOIN kết quả của nhiều truy vấn FREETEXTTABLE để tạo ra kết quả tương đương AND.

2

Dan, tôi thích phương thức SanitizeInput của bạn.Tôi đã tái cấu trúc nó để làm cho nó nhỏ gọn hơn và tăng cường hiệu suất một chút.

static string SanitizeInput(string searchPhrase, int maxLength) 
     { 
      Regex r = new Regex(@";|'|--|xp_|/\*|\*/", RegexOptions.Compiled); 
      return r.Replace(searchPhrase.Substring(0, searchPhrase.Length > maxLength ? maxLength : searchPhrase.Length), " "); 
     } 

     static string SanitizeInput(string searchPhrase) 
     { 
      const int MAX_SEARCH_PHRASE_LENGTH = 200; 
      return SanitizeInput(searchPhrase, MAX_SEARCH_PHRASE_LENGTH); 
     } 

Tôi đồng ý rằng FreeTextTable quá nhẹ của giải pháp.

0

Tất cả tìm kiếm của chúng tôi đều nằm trên các cột trong cơ sở dữ liệu có các ký tự hợp lệ được xác định trước. Thuật toán tìm kiếm của chúng tôi kết hợp điều này với một regex chỉ cho phép các ký tự được xác định trước này. Vì việc thoát này trong chuỗi tìm kiếm là không cần thiết. Regex của chúng tôi loại bỏ mọi nỗ lực tiêm trong mã web (asp & aspx). Đối với nhận xét chuẩn từ người dùng, chúng tôi sử dụng tính năng thoát để thay đổi tất cả các ký tự có thể được sử dụng để gây hại trong SQL, ASP, ASPX, & Javascript.
Trang web TransStar http://latranstar.tann.com/ đang sử dụng một hình thức mở rộng của Soundex để tìm kiếm tên phố, địa chỉ và thành phố ở bất kỳ nơi nào ở miền Nam California. Bản thân Soundex loại bỏ bất kỳ nhu cầu nào về mã chống tiêm vì nó chỉ hoạt động trên các ký tự alpha.

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