2009-08-31 2 views
11

Я построил запрос T-SQL, как это:Обеспокоенность 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 
          ... 
      ) 

Графического интерфейсом для этого поиска будет ASPX страница с одним текстовым полем, в котором пользователь может осуществлять поиск.

Я планирую как-то построить поисковый запрос, чтобы он был как пример выше (@search).

У меня есть некоторые проблемы, хотя:

  • Является ли термин поиска выше пример лучшего или единственным способом включить перегибы всех слов в поиске?
  • Следует отделить слова и построить поисковый запрос в C# или T-SQL. Я склоняюсь к C# для принятия решений/циклов/строительства, но я хочу ваше мнение.
  • Я ненавижу строить SQL динамически из-за риска инъекции. Как я могу защититься от этого?
  • Вместо этого следует использовать FREETEXTTABLE? Есть ли способ заставить FREETEXT искать ВСЕ слова вместо ЛЮБОГО?
  • В общем, как бы вы это сделали?

ответ

3

Недавно я использовал полнотекстовый поиск, поэтому постараюсь ответить на некоторые из ваших вопросов.

• «Я ненавижу строить sql динамически из-за риска инъекции. Как я могу защититься от этого?»

Я использовал метод дезинфицировать так:

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; 
    } 

• Должен ли я использовать FREETEXTTABLE вместо этого? Есть ли способ заставить FREETEXT искать ВСЕ слова вместо ЛЮБОГО?

Я использовал FREETEXTTABLE, но мне было нужно какое-либо из слов. Насколько я читал об этом (и я читал совсем немного), вы должны использовать CONTAINSTABLE для поиска ВСЕ слов или разных комбинаций. FREETEXTTABLE кажется более легким решением, но не тем, которое нужно выбрать, когда вы хотите более глубокие настройки.

0

В вашем примере у вас есть уже заданная переменная @search. Как правило, вы не должны включать динамически конкатенированный текст в исходный SQL, из-за риска инъекции. Тем не менее, вы можете, конечно, установить значение @search в вызывающем объекте команды из вашего приложения. Это полностью отрицает риск инъекционных атак.

Я бы рекомендовал построить поисковый запрос в C#; передавая окончательный термин поиска в качестве параметра, как уже упоминалось.

Насколько я помню, FREETEXTTABLE использует разрывы слов, чтобы полностью разложить условия поиска на отдельные компоненты. Однако оператор FREETEXTTABLE автоматически разлагает слова на флективные эквиваленты, поэтому вам не придется создавать сложный оператор CONTAINSTABLE, если вы решите его использовать.

Вы можете INNER JOIN результаты нескольких FREETEXTTABLE запросов для получения эквивалента AND результат.

2

Дэн, мне нравится ваш метод SanitizeInput.Я реорганизовал его, чтобы сделать его более компактным и немного улучшить производительность.

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); 
     } 

Я согласен с тем, что FreeTextTable является слишком легким в решении.

0

Все наши поисковые запросы находятся в столбцах базы данных с предопределенными действительными символами. Наш алгоритм поиска включает это с регулярным выражением, которое допускает только эти предопределенные символы. Из-за этого экранирование в строке поиска не требуется. Наше регулярное выражение уничтожает любые попытки инъекций в веб-коде (asp & aspx). Для стандартных комментариев пользователей мы используем экранирование, которое изменяет все символы, которые могут быть использованы для вреда в SQL, ASP, ASPX, & Javascript.
Сайт TransStar http://latranstar.tann.com/ использует расширенную форму Soundex для поиска названий улиц, адресов и городов в любой точке Южной Калифорнии. Soundex сам по себе устраняет необходимость в коде для инъекций, поскольку он работает только с альфа-символами.

Смежные вопросы