2016-11-19 10 views
2

Первоначально я обнаружил, что это была проблема, когда я пытался найти термины, которые были добавлены хэштегом, который, как оказалось, является разделителем комментариев в SQL. Поиск не возвращался, потому что он игнорировал #term, который появился после хэштега.Как написать параметризованный SQL-запрос, чтобы предотвратить SQL-инъекцию?

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

Вот фрагмент кода, я работаю с конкретно:

function (term) { 
    term = term.toLowerCase() 
    return db('ticket') 
    .select('*') 
    .where(db.raw('lower(question)'), 'like', `%${term}%`) 
    .orWhere(db.raw('lower(note)'), 'like', `%${term}%`) 
    .orWhere(db.raw('lower(user_name)'), 'like', `%${term}%`) 
} 

Я нашел this и this SO статью, в которой, казалось, близко, а также несколько других вещей. Кроме того, документы Knex и другие источники рекомендуют параметризованное связывание в качестве метода защиты от SQL-инъекции.

У меня возникли проблемы с поиском ясного примера, который может быть объяснен мне в JavaScript или с использованием Knex.

+0

Является ли ваша сортировка БД особенно чувствительной к регистру? Вам не нужно использовать 'LOWER' с оператором' LIKE' - это также означает, что ваш запрос будет работать очень медленно, потому что он не может использовать индексы. – Dai

+0

ИМО. «SQL Injection» - это что-то вроде «Проблема 2000»: много шума, но ничего серьезного. Существует два простых правила, позволяющих избежать «инъекций SQL»: 1) использовать параметризованные запросы на лицевой/средней стороне и 2) установить соответствующую безопасность уровня БД на объекты БД. – Abelisto

+0

Спасибо за ответ. @Dai Я попробовал ваше предложение, но, похоже, он чувствителен к регистру. Я относительно новичок в db land, вы могли бы порекомендовать некоторые ресурсы, чтобы узнать об использовании индексов и сопоставлений, которые вы упомянули? Никогда не слышал условий раньше. –

ответ

6

Я не пользователь Knex.js, но, глядя на документы, кажется, что использование Knex для синтаксиса объекта JavaScript для определения предикатов - это то, как он достигает параметризации.

Однако, поскольку вы используете встроенные функции, вам необходимо использовать whereRaw.

Глядя на документы (http://knexjs.org/#Builder-whereRaw) и (http://knexjs.org/#Raw-Bindings) Я думаю, что вы хотите сделать это:

.whereRaw('question LIKE :term OR note LIKE :term OR user_name LIKE :term', { term: '%' + term + '%' ] }) 

Knex не имеет orWhereRaw, так что вы должны использовать версию от руки, если вы хотите, чтобы логически разделить предикаты:

term = '%' + term + '%'; 

.orWhere(knex.raw('question LIKE ?', [ term ])) 
.orWhere(knex.raw('note  LIKE ?', [ term ])) 
.orWhere(knex.raw('user_name LIKE ?', [ term ])) 

Примечание ? для позиционных параметров, и :term для именованных параметров.

+0

Спасибо за ответ. Да, оба варианта, которые вы представили, работают отлично.Тем не менее, я чувствую, что мне не хватает места, где они принципиально отличаются от того, что я уже делал. У меня была строка шаблона, украшенная% внутри моего orWhere. Устанавливает ли этот термин как объект в первом примере или массив во втором параметризированном привязке? edit: также следует отметить, что я все еще не могу извлечь хэштеги из db, хотя я могу их вставить. –

1

Кажется, что единственный раз, когда вам действительно нужно беспокоиться о вводе sql, вы используете knex.raw() или любую другую чистую команду sql. Другими словами, Knex автоматически ускользает от ввода.

Что касается вопроса о хэштеге, после беспорядка с PG Commander, я обнаружил, что могу найти # отлично. Мне просто нужно было закодировать хэштеги, чтобы отправить их на мой бэкэнд ... Немного смущающе, но сегодня я узнал что-то новое.