CVE-2017-12635
Nov. 18th, 2017 03:13 am![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
В CouchDB обнаружилась пара дырок, которые вместе дают возможность RCE. Это первая критическая уязвимость за 5 лет кстати, и она очень любопытна.
Я примерно год назад писáл о довольно сложной ситуацией с json-парсерами в разных экосистемах. У меня был период ресёча на предмет «не заморочиться ли написанием координатора json-вебстримов на ином, чем пара erlang+js, зверьке» – потому что пара эта не блещет производительностью.
И дырка в CouchDB возможна только потому, что erlang/jiffy и нативный json-парсер в js ведут себя по-разному. В erlang-е возможно создать два свойства внутри объекта под одним ключом, и при выборке будет отдаваться первое. В js создать такой объект невозможно, и при парсе json-а c повтором ключа всегда берётся последнее вхождение.
В CouchDB есть встроенный механизм аутентификации, и учётные записи в нём – json-документы произвольной структуры с несколькими обязательными полями, лежащие в специальном бакете _users. У пользователей есть поле roles[], в котором задаются группы, и есть специальная hard-coded группа _admins, которая даёт круто больше прав.
Обычный пользователь не может поменять список своих ролей, но может поменять другие поля учётки, и контролируется это специальной неудаляемой js-функцией встроенного валидатора бакета с профилями пользователей.
Но можно, будучи залогиненным, отправить свой профиль с полями
Подробный рассказ об уязвимости: justi.cz/security/2017/11/14/couchdb-rce-npm.html, уже выпущено обновление CouchDB в ветках 1.x и 2.x, в котором дырки нет.
---
К счастью, так сложилось, что во всех без исключения системах на CouchDB, которые мы сделали, уязвимость имеет значительно мéньшую тяжесть, а в некоторых системах закрывается даже без необходимости накатывания новой версии БД.
Дело в том, что мы никогда не пользуемся встроенной авторизацией для юзеров фронтэнда (где есть возможность саморегистрации и управления своим профилем), плюс мы никогда не храним эти профили в системном бакете _users.
В бакете _users в лучшем случае живут профили пользователей бэкэнда, и ими всегда управляют или администраторы, или специальный сервис на js с кучей дополнительных проверок.
Я примерно год назад писáл о довольно сложной ситуацией с json-парсерами в разных экосистемах. У меня был период ресёча на предмет «не заморочиться ли написанием координатора json-вебстримов на ином, чем пара erlang+js, зверьке» – потому что пара эта не блещет производительностью.
И дырка в CouchDB возможна только потому, что erlang/jiffy и нативный json-парсер в js ведут себя по-разному. В erlang-е возможно создать два свойства внутри объекта под одним ключом, и при выборке будет отдаваться первое. В js создать такой объект невозможно, и при парсе json-а c повтором ключа всегда берётся последнее вхождение.
В CouchDB есть встроенный механизм аутентификации, и учётные записи в нём – json-документы произвольной структуры с несколькими обязательными полями, лежащие в специальном бакете _users. У пользователей есть поле roles[], в котором задаются группы, и есть специальная hard-coded группа _admins, которая даёт круто больше прав.
Обычный пользователь не может поменять список своих ролей, но может поменять другие поля учётки, и контролируется это специальной неудаляемой js-функцией встроенного валидатора бакета с профилями пользователей.
Но можно, будучи залогиненным, отправить свой профиль с полями
roles:["_admin"],roles:[]
– и стать админом, потому что валидатор увидит последний массив и разрешит запись профиля, а при контроле прав доступа будет использоваться первый.Подробный рассказ об уязвимости: justi.cz/security/2017/11/14/couchdb-rce-npm.html, уже выпущено обновление CouchDB в ветках 1.x и 2.x, в котором дырки нет.
---
К счастью, так сложилось, что во всех без исключения системах на CouchDB, которые мы сделали, уязвимость имеет значительно мéньшую тяжесть, а в некоторых системах закрывается даже без необходимости накатывания новой версии БД.
Дело в том, что мы никогда не пользуемся встроенной авторизацией для юзеров фронтэнда (где есть возможность саморегистрации и управления своим профилем), плюс мы никогда не храним эти профили в системном бакете _users.
В бакете _users в лучшем случае живут профили пользователей бэкэнда, и ими всегда управляют или администраторы, или специальный сервис на js с кучей дополнительных проверок.