Я недавно начал работать над Event Sourcing , когда возник вопрос об обновлении пароля.
Я понимаю следующее:
События хранятся в хранилище событий , которое действует как единый источник правды для текущего приложения и состояния объекта.Мы могли бы воспроизвести серию событий для данного объекта с момента создания указанного объекта и найти текущее состояние объекта.
События должны храниться бесконечно долго, так как разрыв в цепи приводит к потенциально противоречивому состоянию.Мы можем сделать снимок цепочки событий (т. Е. Текущего состояния объекта), если слишком много событий нужно обрабатывать каждый раз для какого-либо представления.
Для меня это имеет очевидные последствия для безопасностикогда дело доходит до чего-то вроде user updated password
.В этом случае мы увидим что-то вроде:
- UserCreatedEvent(user)
- ... // other events that might change the state of the User object
- UserChangedPasswordEvent(updatedPassword)
Проблема, с которой я сталкиваюсь при таком подходе, состоит в том, что для того, чтобы приложение сохраняло согласованное состояние, мы должны хранить все предыдущие пароли пользователя , потому что мы не можем сказать, является ли данный пароль текущим или только одним из предыдущих паролей пользователя (учитывая только UserChangedPasswordEvent
).
Ради аргумента предположим, что приложение хранитпароли с использованием более слабого алгоритма, отличного от BCrypt
, и пароли, которые можно взломать через заданный период времени (т. е. таблица перебора / радуга).
В случае поиска событий злоумышленник, которому удается получить доступв магазине UserChangedPasswordEvent
теперь будет список всех паролей, которые пользователь когда-либо использовал в приложении.В этом сценарии не исключено, что у них будет доступ к хранилищу UserCreatedEvent
, следовательно, также (обычно) уникальной электронной почте пользователя.
Поскольку, к сожалению, большинство обычных пользователей повторно используют пароли на разных платформах, злоумышленник теперь потенциально может получить доступ к любому количеству паролей, которые пользователь мог когда-либо использовать на разных платформах.Это становится еще хуже, если существует такой механизм, как «обязательное возобновление пароля после X времени».
Несмотря на это, является ли это наиболее распространенным подходом при поиске событий и обновлении пароля, или существует стандартизированный способобрабатывать эту часть приложения?Я допускаю, что предпосылка сценария (слабое хеширование паролей) является слабой, но она лучше всего отражает мою точку зрения.
Я могу придумать два способа справиться с этим:
- Зашифрованохранилища событий и / или файловая система;влияет на производительность
UserChangedPasswordEvent
только информирование о самом изменении, пароль хранится в другом месте через другой канал;однако идет вразрез с идеей источников событий)
Обдумываю ли я здесь проблему? Есть ли проблема здесь, если используются правильные алгоритмы хеширования?