Запрос MongoDB $ regex и возможные эксплойты

У нас есть REST API для запроса записей в MongoDB. Очень просто, примерно следующее:

GET /api/items?q=foo

Во время разработки было удобно разрешить регулярные выражения в качестве запроса q. Мы бы просто передали параметр запроса оператору MongoDB $regex и не выполняли никаких экранирований:

db.getCollection('items').find({ name: { $regex: req.query.q, $options: 'i' } });

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

Я, вероятно, недостаточно деструктивен, чтобы придумать такой запрос, поэтому я поискал в Интернете и наткнулся на очень интересное чтение, в котором упоминается несколько атак: Взрывная ловушка квантификатора.

Отбросив тот факт, что упомянутые запросы на приведенной выше странице ведут себя далеко не «катастрофически», как ожидалось (ни в запросах MongoDB, ни в онлайн-инструментах, таких как regex101.com), я все же хотел бы знать:

  1. Это реальная проблема или я преследую несуществующие угрозы?
  2. Следует ли нам полностью отказаться от параметров регулярного выражения?
  3. Есть ли в MongoDB какой-либо механизм (например, тайм-аут) для предотвращения DoS-атак с помощью вредоносных регулярных выражений? (fwiw: мы работаем в среде Node.js)
  4. Существуют ли библиотеки для обнаружения таких атак перед отправкой запроса?

Какие-нибудь библиотеки? Я не уверен, но понимание того, что такое ReDoS-атака, поможет создать свои собственные условия. Более того, запрет кластеров, таких как захватывающие или не захватывающие группы, снизит этот риск. Вам также могут не понадобиться регулярные выражения, но некоторые шаблоны, такие как некоторые расширения, например, * или ?.

revo 09.10.2018 18:38
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
8
1
1 029
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мое довольно личное чутье говорит: не беспокойтесь. Но опять же, если вам все же или даже нужно, то вот несколько советов, как справиться с этим требованием:

  1. Вы можете определить максимальное время, в течение которого запрос может выполняться, для использования maxTimeMS ().
  2. Вы можете попытаться очистить ввод регулярного выражения, но я сомневаюсь, что существуют библиотеки, которые помогут вам в этом, учитывая бесконечные варианты потенциально длительных сложных запросов. Ограничение длины регулярного выражения тоже может помочь, но с другой стороны, вероятно, лишает пользователя возможности удобного поиска с использованием произвольных фильтров.
  3. Вы можете предоставить более структурированный ввод запроса, например позволять пользователю вводить только один буквенно-цифровой текст, который вы затем должны заключить в регулярное выражение на стороне сервера, например, запросы "начинается с", "содержит" или "заканчивается на" или что-то в этом роде.
  4. Вы можете разрешить только один параллельный запрос для каждого пользователя (сеанс? Ip?), Который, вероятно, немного поможет против фатальных DoS-атак, но, конечно, не против распределенных ... Или вы даже можете разрешить только один параллельный вызов этой конечной точки через вся система.

Другие вопросы по теме