Выбор парольного менеджера — непростая задача. Если не считать «Блокнот» с шифрованием текстового файла, то в этой области нет явного лидера. Фундаментальный вопрос: безопасно ли использовать облачные сервисы или принципиально хранить пароли только локально? Кто-то считает, что использование облачных сервисов всё-таки повышает риски. И вот поступил очередной аргумент в этом споре. Только что парольный менеджер LastPass закрыл три уязвимости (одна для расширения под Chrome, две для расширения под Firefox), которые позволяли вредоносному сайту прямо извлекать пароли LastPass. Как обычно, причина уязвимости — ошибка программистов.
Какой же парольный менеджер теперь лучше? Может, вернуться всё-таки к «Блокноту»?
В корпоративном блоге LastPass сообщается, что об уязвимостях им сообщил специалист по безопасности Тэвис Орманди (удивительно, что львиную долю всех багов в популярном софте находят одни и те же люди) из хакерской команды Google Project Zero.
LastPass говорит, что не заметила кражи паролей пользователей и советует обновиться на последние версии расширения, где эта уязвимость закрыта, если они ещё не обновились автоматически:
- Firefox: 4.1.36
- Chrome: 4.1.43
- Edge: 4.1.30
- Opera: 4.1.28
Предположим, что кражи паролей действительно не произошло. Но как конкретно злоумышленники могли произвести такую кражу?
Первая уязвимость (Firefox 3.3.2 message-hijacking) для старой ветки расширения под Firefox эксплуатирует схему парсинга URL в 3.3.2, которая позволяла вредоносному веб-сайту выдать себя за легитимный сайт и тем самым вынудить LastPass предоставить учётные данные. Информация об этом баге поступила в LastPass в прошлом году — в июле уязвимость была закрыта, но только для новой ветки 4.X, и её просто забыли перенести в ветку 3.Х.
В прошлом году специалист по безопасности Матиас Карлссон (Mathias Karlsson) подробно рассказывал об этом позорном баге с URL-парсером в LastPass.
Вот как выглядел парсер (функция lpParseUri в расширении LastPass):
var fixedURL = URL.match(/^(.*:\/\/[^\/]+\/.*)@/);
fixedURL && (url = url.substring(0, fixedURL[1].length) + url.substring(fixedURL[1].length).replace(/@/g, "%40"));
Такое обращение с «собачками» означает, что URL типа
http://avlidienbrunn.se/@twitter.com/@hehe.php
браузер воспринимал как адрес на домене avlidienbrunn.se
, а расширение LastPass воспринимало как адрес twitter.com/@hehe.php
. Соответственно, функция автозаполнения передавала домену avlidienbrunn.se
пароль для домена twitter.com
.Эту уязвимость закрыли год назад в актуальной ветке LastPass, все посмеялись и забыли. Сейчас оказалось, что в ветке 3.Х баг ещё остался. Разработчики LastPass объясняют, что ту ветку формально закрыли ещё в апреле, то есть её поддержкой никто не занимался. И если до сих пор остались пользователи старых версий, то им настоятельно рекомендуется перейти на 4.1.36.
Второй баг
Вторая уязвимость, которую LastPass закрыла вчера, уже свеженькая. И она затрагивает не только версии для Firefox, но и версии под Chrome и Edge. Как и прошлый баг, здесь вредоносный сайт может выдать себя за доверенный и выудить пароль. Более того, в случае использования бинарного компонента LastPass было возможно даже удалённое исполнение кода, что совершенно недопустимо.
В сообщении баг-трекера Chromium Тэвис Орманди объяснил, что проблема в скрипте websiteConnector.js, который используется только на домене 1min-ui-prod.service.lastpass.com. Вот он указан в манифесте:
{
"matches": [
"https://1min-ui-prod.service.lastpass.com/*"
],
"js": [
"1minsignup/chrome/websiteConnector.js"
],
"all_frames": true,
"run_at": "document_end"
},
Содержимое скрипта:
$ uglifyjs --beautify < 1minsignup/chrome/websiteConnector.js
...
window.addEventListener("message", function(e) {
e.data.fromExtension || chrome.runtime.sendMessage(e.data, function(e) {});
});
Передача неаутентифицированных объектов window в расширение из скрипта websiteConnector.js позволяет кому угодно использовать эту функцию:
win = window.open("https://1min-ui-prod.service.lastpass.com/");
win.postMessage({}, "*");
И получить доступ ко всем внутренним командам LastPass RPC. Там сотни вызовов, в том числе передача паролей. При использовании бинарного компонента LastPass можно даже запустить произвольный код:
win = window.open("https://1min-ui-prod.service.lastpass.com/");
win.postMessage({fromExtension: false, cmd: "openattach", attachkey: "d44479a4ce97554c24399f651ca76899179dec81c854b38ef2389c3185ae8eec", data: "!8uK7g5j8Eq08Nr86mhmMxw==|1dSN0jXZSQ51V1ww9rk4DQ==", mimetype: "other:.bat"}, "*");
Закрытый баг в расширении для Chrome совпадает с одним из закрытых багов в расширении для Firefox, только там понадобилось внести некоторые дополнения.
Как говорил Матиас Карлссон в прошлом году, нахождение таких уязвимостей — не повод отказаться от парольных менеджеров.
Кстати, Microsoft ещё не одобрила у себя новую версию расширения для Edge. Похоже, что пользователей LastPass на этом браузере всё ещё можно эксплуатировать.