Эта статья — первая из серии статей, которые я пишу о запуске различных SaaS-продуктов и веб-сайтов за последние 8 лет. Я поделюсь некоторыми проблемами, с которыми мне пришлось иметь дело, уроками, которые я извлек, ошибками, которые я совершил, и, возможно, несколькими вещами, которые пошли правильно. Позвольте мне знать, что вы думаете!
Еще в 2019 или 2020 году я решил переписать весь бэкэнд для Блок отправителя, SaaS-приложение, которое, помимо других функций, помогает пользователям создавать более эффективные блоки электронной почты. В процессе я добавил несколько новых функций и обновился до гораздо более современных технологий. Я запустил тесты, развернул код, вручную протестировал все в рабочей среде, и, за исключением нескольких случайных мелочей, все, казалось, работало отлично. Хотелось бы, чтобы это был конец истории, но…
Несколько недель спустя клиент уведомил меня (что само по себе неловко), что услуга не работает, и что они получают много писем, которые следует заблокировать, в свой почтовый ящик, поэтому я провел расследование. Во многих случаях эта проблема возникает из-за того, что Google удаляет соединение нашей службы с учетной записью пользователя, что система обрабатывает, уведомляя пользователя по электронной почте и прося его повторно подключиться, но на этот раз это было что-то другое.
Похоже, что серверная часть, которая занимается проверкой электронной почты на наличие пользовательских блоков, продолжала давать сбой каждые 5-10 минут. Самое странное — в журналах не было ошибок, с памятью все было в порядке, но процессор время от времени давал скачки, казалось бы, в случайное время. Таким образом, в течение следующих 24 часов (с 3-часовым перерывом на сон — извините, клиенты 😬) мне приходилось вручную перезапускать рабочий процесс каждый раз, когда он падал. По какой-то причине служба Elastic Beanstalk слишком долго ждала перезапуска, поэтому мне пришлось делать это вручную.
Отладка проблем в рабочей среде всегда болезненна, особенно потому, что я не мог воспроизвести проблему локально, не говоря уже о том, чтобы выяснить, что ее вызвало. Итак, как любой «хороший» разработчик, я только начал авторизоваться. многое и ждал, пока сервер снова выйдет из строя. Поскольку процессор периодически перегружался, я решил, что это не проблема макроса (например, когда у вас заканчивается память), а, вероятно, вызвано конкретным электронным письмом или пользователем. Поэтому я попытался сузить круг вопросов:
- Был ли сбой при использовании определенного идентификатора электронной почты или типа?
- Был ли сбой у конкретного клиента?
- Вылетал ли он через какие-то регулярные промежутки времени?
После нескольких часов работы и просмотра журналов дольше, чем мне хотелось бы, в конце концов я сузил круг до конкретного клиента. После этого пространство поиска немного сузилось — скорее всего, это было правило блокировки или конкретное электронное письмо, которое наш сервер продолжал повторять. К счастью для меня, это было первое, и эту проблему гораздо проще отладить, учитывая, что мы являемся компанией, очень ориентированной на конфиденциальность, и не храним и не просматриваем какие-либо данные электронной почты.
Прежде чем мы углубимся в конкретную проблему, давайте сначала поговорим об одной из функций Block Sender. В то время у меня было много клиентов, которые просили блокировать подстановочные знаки, что позволило бы им блокировать определенные типы адресов электронной почты, которые следовали одному и тому же шаблону. Например, если вы хотите заблокировать все электронные письма с маркетинговых адресов электронной почты, вы можете использовать подстановочный знак marketing@*
и он заблокирует все электронные письма с любого адреса, который начинается с marketing@
.
Одна вещь, о которой я не подумал, это то, что не все понимают, как работают подстановочные знаки. Я предполагал, что большинство людей будут использовать их так же, как я, как разработчик, используя один *
для представления любого количества символов. К сожалению, этот конкретный пользователь предположил, что вам нужно использовать один подстановочный знак для каждого символа, который вы хотите сопоставить. В их случае они хотели заблокировать все электронные письма с определенного домена (это встроенная функция Block Sender, но они, должно быть, не осознали этого, что само по себе является целой проблемой). Поэтому вместо использования *@example.com
, они использовали **********@example.com
.
Точка зрения: Наблюдение за тем, как пользователи используют ваше приложение…
Для обработки подстановочных знаков на нашем рабочем сервере мы используем библиотеку Node.js. согласовани, который помогает при сопоставлении глобальных объектов, превращая его в регулярное выражение. Эта библиотека затем превратится **********@example.com
во что-то вроде следующего регулярного выражения:
/[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*@example.com/i
Если у вас есть опыт работы с регулярными выражениями, вы знаете, что они могут очень быстро усложниться, особенно на вычислительном уровне. Сопоставление приведенного выше выражения с текстом любой разумной длины становится очень затратным в вычислительном отношении, что в конечном итоге приводит к перегрузке ЦП на нашем рабочем сервере. Вот почему сервер аварийно завершал работу каждые несколько минут; он застревал при попытке сопоставить сложное регулярное выражение с адресом электронной почты. Таким образом, каждый раз, когда этот пользователь получал электронное письмо, в дополнение ко всем повторным попыткам, которые мы предусмотрели для обработки временных сбоев, это приводило к сбою нашего сервера.
Итак, как я это исправил? Очевидно, что быстрым решением было найти все блоки с несколькими подстановочными знаками подряд и исправить их. Но мне также нужно было лучше обрабатывать вводимые пользователем данные. Любой пользователь может ввести регулярное выражение и вывести из строя всю систему с помощью ReDoS-атака.
Ознакомьтесь с нашим практическим руководством по изучению Git с рекомендациями, принятыми в отрасли стандартами и прилагаемой памяткой. Перестаньте гуглить команды Git и на самом деле изучить это!
Обработка этого конкретного случая была довольно простой — удалить последовательные символы подстановки:
block = block.replace(/*+/g, '*')
Но это по-прежнему оставляет приложение открытым для других типов ReDoS-атак. К счастью, существует ряд пакетов/библиотек, которые помогут нам и с этими типами:
Используя комбинацию приведенных выше решений и других мер безопасности, я смог предотвратить повторение этого. Но это было хорошим напоминанием о том, что никогда нельзя доверять пользовательскому вводу и всегда следует его очищать перед использованием в своем приложении. Я даже не знал, что это потенциальная проблема, пока это не случилось со мной, так что, надеюсь, это поможет кому-то другому избежать той же проблемы.
Есть вопросы, комментарии или хотите поделиться собственной историей? Обратитесь к Twitter!
- SEO-контент и PR-распределение. Получите усиление сегодня.
- PlatoData.Network Вертикальный генеративный ИИ. Расширьте возможности себя. Доступ здесь.
- ПлатонАйСтрим. Интеллект Web3. Расширение знаний. Доступ здесь.
- ПлатонЭСГ. Углерод, чистые технологии, Энергия, Окружающая среда, Солнечная, Управление отходами. Доступ здесь.
- ПлатонЗдоровье. Биотехнологии и клинические исследования. Доступ здесь.
- Источник: https://stackabuse.com/behind-the-scenes-never-trust-user-input/
- :имеет
- :является
- :нет
- $UP
- 1
- 20
- 2019
- 2020
- 24
- 8
- a
- в состоянии
- О нас
- выше
- Учетная запись
- на самом деле
- добавленный
- дополнение
- адрес
- адреса
- снова
- против
- Все
- позволять
- в одиночестве
- причислены
- всегда
- среди
- an
- и
- любой
- приложение
- Применение
- МЫ
- гайд
- AS
- спрашивающий
- предполагается,
- At
- нападки
- избежать
- знать
- Backend
- BE
- бобовое дерево
- становится
- было
- до
- за
- за кулисами
- не являетесь
- Лучшая
- Немного
- Заблокировать
- блокирование
- Блоки
- граница
- Ломать
- построенный
- но
- by
- CAN
- Может получить
- заботится
- случаев
- вызванный
- Причинение
- определенный
- персонаж
- символы
- контроль
- код
- сочетание
- Комментарии
- Компания
- комплекс
- сложный
- вычислительный
- связи
- исправить
- может
- не мог
- Crash
- разбившийся
- Грохот
- Создайте
- клиент
- Клиенты
- данным
- дело
- решенный
- развернуть
- Застройщик
- DID
- А не было
- do
- домен
- Дон
- вниз
- два
- каждый
- легче
- еще
- Писем
- конец
- закончился
- окончания поездки
- Enter
- Весь
- ошибки
- особенно
- Даже
- со временем
- Каждая
- все члены
- многое
- пример
- дорогим
- опыт
- выражение
- сбои
- достаточно
- далеко
- Особенность
- Особенности
- несколько
- фигура
- фигурный
- Найдите
- конец
- Во-первых,
- фиксированный
- Фокус
- следует
- после
- Что касается
- Бывший
- от
- получить
- получающий
- GIF
- идти
- данный
- хорошо
- большой
- инструкция
- было
- обрабатывать
- Ручки
- практический
- произошло
- Случай
- Есть
- помощь
- помогает
- С надеждой
- ЧАСЫ
- зависать
- Как
- HTTPS
- i
- ID
- if
- in
- включены
- вход
- вместо
- в
- вопрос
- вопросы
- IT
- саму трезвость
- работа
- всего
- хранится
- Знать
- Фамилия
- новее
- узнали
- изучение
- Длина
- Уроки
- позволять
- уровень
- LG
- Библиотека
- такое как
- Вероятно
- ll
- в местном масштабе
- каротаж
- Длинное
- дольше
- смотрел
- много
- Макрос
- сделанный
- вручную
- многих
- Маркетинг
- Совпадение
- согласование
- может быть
- me
- Память
- Минут
- ошибки
- Модерн
- современные технологии
- БОЛЕЕ
- самых
- много
- с разными
- должен
- Узкий
- родной
- необходимый
- никогда
- Новые
- Новые функции
- следующий
- нет
- узел
- Node.js
- уведомляющее
- номер
- шансы
- of
- on
- ONE
- открытый
- or
- Другое
- наши
- внешний
- собственный
- боль
- часть
- особый
- шаблон
- Люди
- Платон
- Платон Интеллектуальные данные
- ПлатонДанные
- Блог
- потенциал
- практическое
- предотвращать
- вероятно
- Проблема
- процесс
- Производство
- Продукция
- Вопросы
- САЙТ
- быстро
- вполне
- случайный
- RE
- достигать
- реализованный
- причина
- разумный
- получила
- воссоединиться
- регулярное выражение
- регулярный
- напоминание
- удаление
- удаление
- представлять
- правую
- кольцо
- Правило
- Run
- Бег
- s
- SaaS
- защитные меры
- то же
- Сцены
- Поиск
- казалось
- по-видимому
- отправитель
- Серии
- сервер
- обслуживание
- Shadow
- Поделиться
- разделение
- лист
- должен
- просто
- с
- спать
- So
- Решения
- некоторые
- Кто-то
- удалось
- Space
- конкретный
- шип
- Стекабьюс
- стандартов
- и политические лидеры
- По-прежнему
- Stop
- магазин
- История
- система
- взять
- Говорить
- технологии
- временный
- проверенный
- тестов
- текст
- чем
- который
- Ассоциация
- их
- Их
- тогда
- Там.
- Эти
- они
- задача
- вещи
- think
- этой
- время
- раз
- в
- слишком
- переход
- пыталась
- Доверие
- пытается
- ОЧЕРЕДЬ
- Поворот
- напишите
- Типы
- понимает
- К сожалению
- до
- повышен
- us
- использование
- используемый
- Информация о пользователе
- пользователей
- через
- различный
- Ve
- очень
- с помощью
- Вид
- Ожидание
- хотеть
- стремятся
- законопроект
- был
- наблюдение
- Путь..
- we
- веб-сайты
- Недели
- ЧТО Ж
- пошел
- были
- Что
- когда
- который
- все
- зачем
- Википедия.
- желание
- Работа
- работник
- работает
- бы
- письмо
- лет
- Ты
- ВАШЕ
- зефирнет