Как выйти из строки в Ruby для защиты от Внедрения SQL? (Никакие направляющие)

Я думаю, что ваша проблема вызвана непредсказуемостью взаимодействия средства разбиения по словам с знаками препинания в данных. Полнотекстовый поиск основан на концепции строк символов, не включая пробелы и знаки препинания. Когда двигатель строит указатель, он видит периоды и странным образом разбивает слово.

В качестве примера я составил небольшую таблицу с тремя указанными вами значениями ...

VALUES (1,'3.7.21.1'),(2,'3.7.21'),(3,'3.72.21')

Теперь, когда я делаю ваш выбор, я получаю результаты по всем четырем ... но не те результаты, которые я ожидаю.

Для меня это возвращает все три значения

SELECT * FROM containstext WHERE CONTAINS(secondid, '"3.7.2*"')

, и это возвращает только 3.7.21

SELECT * FROM containstext WHERE CONTAINS(secondid, '"3.7*"')

Итак, давайте запустим это и посмотрим на содержание полнотекстового индекса

SELECT * FROM sys.dm_fts_index_keywords(db_id('{databasename}'), object_id('{tablename}'))

Для моих результатов (ваши, вероятно, отличаются) у меня есть следующие значения display_term

display_term     document_count
    21              3
    3               3
    3.7.21          1
    7               2
    72              1

Итак, давайте посмотрим на первый критерий поиска '"3.7.2*"' Если я вставлю это в sys.dm_fts_parser ...

select * from sys.dm_fts_parser('"3.7.2*"', 1033, NULL, 0)

... это показывает мне, что он ломается со спичками на

3
7
2

Но если я сделаю ...

select * from sys.dm_fts_parser('"3.7*"', 1033, NULL, 0)

Я получаю одно точное совпадение с термином 3.7, и sys.dm_fts_index_keywords ранее говорил мне, что у меня есть только один документ / строка, содержащая 3.7

. дополнительная странность, потому что числа 0-9 обычно находятся в системных стоп-словах и могут быть исключены из индекса, потому что они считаются бесполезными. Это может быть то, почему это работает, когда вы переходите на буквы.

Кроме того, я знаю, что вы решили заменить LIKE, но Microsoft предложила использовать только буквенно-цифровые символы в полнотекстовых индексах и, если вам нужно использовать не алфавитно-цифровые символы в критериях поиска , вы должны использовать как. Возможно, изменить периоды на какую-либо буквенно-цифровую замену, которая не будет использоваться в нормальных значениях?

14
задан Andy Lester 11 March 2010 в 15:58
поделиться

4 ответа

Вы не должны использовать направляющие, Вы могли просто require 'activerecord' и используйте его, как Вы были бы в направляющих (определите модели и используйте их). Что Вы делаете, там только изобретает велосипед.

2
ответ дан 1 December 2019 в 12:27
поделиться

Если возможно, используйте модуль DBI Ruby, и вместо того, чтобы пытаться заключить Ваши строки в кавычки, используйте параметризованные подготовленные запросы, как это:

dbh = DBI.connect("DBI:Mysql:test:localhost", "testuser", "testpass")
sth = dbh.prepare("INSERT INTO people (id, name, height) VALUES(?, ?, ?)")
File.open("people.txt", "r") do |f|
  f.each_line do |line|
    name, height = line.chomp.split("\t")
    sth.execute(nil, name, height)
  end
end

Заключение в кавычки будет обработано правильно для Вас, и инжекции будут вещью прошлого.

Править: Обратите внимание, что этот пример показывает ноль, передаваемый как первый параметр для выполнения (). Это соответствует первому? в запросе, и переводится в "ПУСТОЙ УКАЗАТЕЛЬ" модулем DBI. Другие параметры так же правильно заключаются в кавычки и вставляются в запрос.

17
ответ дан 1 December 2019 в 12:27
поделиться

Напишите небольшую функцию для заключения строк в кавычки. Я думаю, что Rails просто использует что-то вроде этого:

def quote_string(v)
  v.to_s.gsub(/\\/, '\&\&').gsub(/'/, "''")
end
3
ответ дан 1 December 2019 в 12:27
поделиться

Не пытайтесь дезинфицировать данные. Используйте подготовленные отчеты. См. также http://bobby-tables.com/ruby.html

1
ответ дан 1 December 2019 в 12:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: