Bounty-программа в Badoo
Сегодня у многих IT-компаний есть собственные bounty-программы (или программы по поиску уязвимостей). Badoo — в их числе.
В этой статье я расскажу о том, как мы, не имея отдела информационной безопасности, запустили и ведем свою bounty-программу. Я расскажу о проблемах, с которыми мы столкнулись, как их решали и каким образом пришли к тому, что у нас сейчас есть. И, конечно, упомяну о некоторых интересных багах, присланных участниками этой программы.
Со времени старта нашей bounty-программы прошло три года. Нам до сих пор продолжают присылать сообщения участники со всего мира.
Мы хотим усилить интерес к ней, в том числе со стороны иностранных исследователей. Поэтому мы, во-первых, открыли страничку с нашей программой на крупнейшем портале исследователей hackerone.com, а во-вторых — увеличили суммы вознаграждений за найденные уязвимости! Теперь сумма вознаграждения, в зависимости от категории, начинается от £100 и может достигать £1000, сумма супер-премии составляет £2000 (а это более 200 000 рублей по текущему курсу!) и даже больше, если обнаруженная уязвимость представляет реальную угрозу для наших пользователей.
Badoo — это крупнейший в мире сервис знакомств. Тут можно встретить свою любовь, завести новых друзей или же просто найти собеседников, находящихся поблизости.
На сегодняшний день в Badoo зарегистрировано более 300 миллионов пользователей, которые говорят более чем на 50 языках и живут по всему миру. Работу этой системы поддерживают около 3000 серверов, расположенных в четырех дата-центрах (в Америке, Европе, Азии и России). Наш продукт — это набор приложений для всех популярных мобильных платформ, мобильный веб и веб-версия для десктопного браузера. Мы — highload-проект, и в пиках трафика у нас 70–80 тысяч запросов в секунду.
Очевидно, что система довольно масштабная и требует немало работы по разным направлениям, в том числе и в сфере информационной безопасности.
Как это ни странно, у нас нет отдела информационной безопасности. И специалистов, занимающихся исключительно этим направлением, у нас тоже нет.
Тем не менее мы дорожим нашими пользователями и заботимся о безопасности их данных. Несмотря на то, что мы не банк, не система онлайн-платежей и у нас нет возможности вывода средств (но есть зачисление средств, которые переводятся во внутреннюю валюту «кредиты Badoo»), у нас довольно много данных, которые надо защищать.
Масла в огонь подливает и продиктованная бизнесом необходимость не лишать пользователей удобства. Так, например, у нас есть фича, когда в письме пользователю имеется прямая ссылка на доступ к аккаунту без небходимости ввода логина и пароля. Очевидно, что это огромный риск с точки зрения безопасности. Мы стараемся подстраховаться по максимуму, и у нас имеются механизмы защиты данных пользователя даже в этом случае. Но, конечно, никто не идеален.
Почему у нас нет выделенного отдела — сложный вопрос, отвечая на который я бы хотел напомнить, что наш проект вырос из стартапа. А любой стартап изначально нацелен на быстрое развитие и достижение бизнес-целей; он не сильно фокусируется на качестве, безопасности и прочих очевидных для зрелых проектов аспектах. Именно поэтому большинство стартапов задумывается о своем отделе тестирования далеко не с самого начала, а об отделе информацинной безопасности и того позже. И это нормально.
До сих пор в нашей компании применяются некоторые методы и подходы, характерные для стартапа. Информационной безопасностью в целом мы занимались с самого начала (наши ребята — профессионалы своего дела), но вот системного подхода не было. Вероятно, когда-нибудь и мы придем к необходимости в отдельных специалистах или целом отделе, занимающемся информационной безопасностью.
А сегодня мы обеспечиваем безопасность и поддерживаем bounty-программу следующим образом:
- системные администраторы занимаются инфраструктурной, сетевой и прочей безопасностью. И они начали это делать раньше всех остальных команд;
- разработчики (в том числе при проведении код-ревью) проверяют код с точки зрения безопасности и возможных ошибок;
- тестировщики в автотестах и при проверке задач вручную тоже проверяют безопасность фич (например, несанкционированный доступ или инъекции кода);
- мы регулярно проводим проверки автоматическими инструментами, в частности Skipfish и Acunetix;
- мы сертифицированы по PCI DSS (у нас первый, самый высокий уровень). В рамках этого стандарта регулярно проводится множество мероприятий по обеспечению безопасности: полная изоляции процесса разработки и выкладки кода и оборудования, обрабатывающего платежи; регулярные тесты на проникновение; регулярные аудиты инфраструктуры и много чего еще. Все эти мероприятия позволили нам не только получить высшую категорию по стандарту, но и удерживать ее вот уже несколько лет;
- саму систему разработки кода, фреймворк, шаблонизатор, среду эксплуатации и другие вещи мы постарались сделать так, чтобы, во-первых, минимизировать возможность ошибки, а во-вторых — минимизировать последствия возможных ошибок. Самый простой пример: мы пропатчили свой php-fpm так, чтобы он исполнял PHP-код только из определенных директорий (закрытых на запись, разумеется). Таким образом, даже если допустить, что на наши сервера удалось залить сторонний код, мы минимизируем возможность его запуска.
Давным-давно нам, бывало, помогали сторонние специалисты по безопасности. Кого-то мы просили сами, кто-то писал нам о багах по собственной воле и получал за это вознаграждение. Но сам процесс был неорганизованным, поэтому мы решили его систематизировать, упорядочить и поставить на поток.
Пару лет назад мы всерьез задумались о постоянной bounty-программе, тем более что, с одной стороны, это своего рода челлендж, который позволил бы нам выйти на новый уровень, а с другой — независимая проверка, которая помогла бы нам понять, как обстоят наши дела с безопасностью.
Подготовка
Разумеется, мы не стали сразу браться за реализацию, а начали с подготовки и провели несколько внутренних проверок, чтобы повысить уверенность в том, что мы готовы.
- Убедились, что доступы к базам и другим ресурсам в порядке. Проверили права на запуск, запись и прочие действия для системных пользователей на серверах. Разумеется, работы было проделано немало и многое пришлось переделать, чтобы система стала удовлетворять новым требованиям. В некоторых местах меняли API доступа, чтобы это можно было контролировать.
- Усилили защиту от XSS-атак для нашей системы шаблонизации. Теперь все стало экранироваться по умолчанию, а не только тогда, когда программист явно это напишет.
- Провели несколько стадий внутреннего аудита всей системы, кода, окружения.
- Подготовили инструментарий для обработки заявок пользователей. Мы не хотели сразу запускать большую программу. Для начала решили поэкспериментировать и запустить ее на месяц, поэтому сильно заморачиваться инструментами тоже не стали. В первую очередь мы организовали систему обработки заявок в Google Группах (у нас в компании используется почта Google). С точки зрения кастомизации интерфейс у сервиса довольно гибкий, поэтому многие вещи (принята ли заявка, какая ей присвоена категория, ушла ли она в разработку, заплатили ли за нее деньги) сделать было несложно.
- Начать программу мы решили с основного веб-сайта, чтобы посмотреть, как она пойдет и насколько будет эффективной.
- Также было решено провести программу в рускоязычном сегменте сети, поскольку мы, во-первых, уже были знакомы с несколькими сильными исследователями из России, которых попросили поучаствовать, а во-вторых — опасались провала мирового масштаба в случае неудачи.
В интерфейсе корпоративного сайта мы сделали страничку, куда выводились заявки, их статусы и категории. Описание уязвимостей появлялись на этой странице только после того, как уязвимость закрывалась. Новую заявку можно было отправить нам через эту же страницу.
Это оказалось очень удобно: люди получали в письме от нас номер заявки и могли следить за ее состоянием в этом же списке. А еще они могли давать ссылку на эту страницу другим, повышая собственную карму.
В качестве дополнительной мотивации мы сделали рейтинг участников, в котором принималось во внимание не только количество принятых заявок от конкретного участника, но и их критичнось. После окончания месячника мы наградили лидеров рейтинга специальными призами.
Эта страничка также помогала нам указывать участникам на дубликаты. В случае дублирования участник получал уведомление с номером уже принятой заявки. В результате он мог на этой странице отслеживать статус таких заявок.
При оценке багов, найденных участниками, мы не стали опираться на распространенные системы оценок уязвимостей, таких как, к примеру, OWASP. Напротив, мы решили присуждать категорию в зависимости от потенциального ущерба, который уязвимость можно нанести нам и нашим пользователям. Таких категорий мы ввели 5, и в денежном эквиваленте они оценивались в сумму от 50 до 500 фунтов стерлингов.
На первый взгляд, это может показаться странным, но мы руководствовались тем, что зачастую не самая критичная по версии OWASP уязвимость может нанести нам серьезный вред, поэтому ее надо оценивать выше. К тому же мы предусмотрели супер-премию в £2000 и выше в случае обнаружения особо критичной уязвимости. Так мы решили дополнительно мотивировать наших исследователей не только сообщать об уязвимости, но и придумать для нее максимально эффективный вектор эксплуатации. Далее в статье я приведу пример простой XSS-уязвимости, за которую мы выдали супер-премию из-за необычного и очень интересного вектора атаки.
Конкурс
Итак, «день Д» наступил. Мы запустили программу, анонсировав ее в нескольких источниках, и стали ждать результатов. Напомню, что мы запускали ее всего лишь на месяц. Он был напряженным, но очень полезным для нас. Результаты «месячника безопасности» в Badoo были такими:
- мы получили около 500 заявок с потенциальными угрозами;
- около 50 из них оказались дубликатами;
- примерно 150 заявок были просто багами или пожеланиями к улучшению, не имеющими отношения к безопасности;
- чуть более 50 были реальными уязвимостями;
- более половины уязвимостей составили различные CSRF.
Основной процент багов, присланных в течение нескольких дней, составили CSRF. Затронуты были в основном страницы, на которых пользователи заполняли информацию о себе, загружали фото и так далее. Нельзя сказать, что защиты от CSRF-атак на тот момент у нас совсем не было. Многие страницы были защищены сессионным токеном. Тем не менее, как оказалось, не все действия пользователя на сайте были защищены от CSRF-угроз.
Мы отреагировали быстро и уже через несколько дней после старта конкурса запустили большой проект по защите пользовательских данных — анти-CSRF. Все страницы и веб-сервисы мы переделали таким образом, чтобы они стали проверять CSRF-токены по умолчанию. Так мы закрыли практически все CSRF-уязвимости на сайте.
Интересные баги
Топ-3 наиглупейших багов, полученных во время первого «месячника безопасности» выглядели так:
- В нашем приложении есть «кредиты» — искуственная внутренняя валюта системы, на которую пользователь обменивает реальные деньги, а затем покупает некоторые сервисы. Найденная ошибка была очень глупой и существовавала в системе довольно-таки давно. Если бы не bounty-программа, мы о ней бы еще долго не узнали. Суть заключалась в том, что из-за ошибки в коде, несмотря на все предосторожности, количество кредитов, которые попадут на счет пользователя после оплаты, бралось напрямую из формы. Правка этих значений в html-коде страницы позволяла злоумышленнику, заплатив небольшую сумму денег, положить себе на счет кредитов больше положенного. Мы провели анализ транзакций и выплатили нашедшему эту уязвимость солидное вознаграждение (хотя ею никто, кроме него, не воспользовался).
- Почти такой же простой была и вторая ошибка. Она заключалась в том, что в одном из обработчиков неверно валидировалось значение параметра, идентефицирующего пользователя при изменении его данных. В результате, поменяв user_id в запросе, можно было менять некоторую информацию других пользователей. Как видите, обе ошибки просты, тем не менее они получили наивысшую оценку.
- Каким же был третий баг? В Badoo есть возможность привязывать к своему аккаунту аккаунты внешних соцсетей. После этого через них можно авторизоваться во внутреннем аккаунте. Так вот, в механизме привязки была ошибка, которая позволяла привязать свою учетную запись во внешней соцсети к чужому внутреннему аккаунту и, соответственно, получить доступ к чужому профилю.
Что дальше?
За месяц конкурса мы научились реагировать на заявки от участников в течение нескольких часов, починили баги и создали отдельный проект по защите от CSRF-атак. Стало понятно, что эта программа — дело хорошее и нужное. Она полностью оправдала время и ресурсы, затраченные на ее подготовку и реализацию. Поэтому мы решили двигаться дальше и стали готовиться к постоянной программе по поиску уязвимостей в системе безопасности Badoo, немного изменив формат.
В течение месячника мы поняли, как должен выглядеть удобный flow для обработки заявок, и перевели его в JIRA, поскольку трекинг всех задач в нашей компании делается именно в этой системе.
Простой flow в Google Группах выглядел следующим образом:
Заявки от участников попадали к нам двумя путями: через форму на корпоративном сайте и специальный email-адрес. Далее жюри конкурса оценивало заявки и отправляло их (в случае реальных угроз) в разработку конкретным командам. Общаться с участниками на этом этапе нам помогала Developer relations manager, хотя многие письма можно было генерировать автоматически.
Flow в Jira, который мы сделали для постоянной программы, выглядел немного иначе и уже включал в себя автоматические ответы участникам, исключая человеческий фактор.
Также в постоянную программу мы решили добавить и мобильные приложения.
Примерно в то же время мы попали в список bounty-программ Bugcrowd, что принесло нам дополнительную популярность и привлекло внимание исследователей со всего мира. Усилив анонсирование, мы запустили программу.
Результаты постоянной программы
Результаты не были такими же впечатляющими, как после месячника — поток нерелевантных репортов об узявимостях был больше. Тем не менее за первый год работы «большой» программы мы получили сообщения о нескольких интересных багах.
- Нам прислали около 870 заявок.
- Около 50 репортов из них были реальными уязвимостями безопасности.
- Более 30 заявок, присланных за первый год, оказались дубликатами.
- Более 20 присланных багов были про мобильные приложения.
Как и ожидалось, «шума» стало больше, но и полезных репортов тоже было немало, поэтому результатом программы в целом мы довольны.
Интересные баги
Много интересных багов за первый год нам прислали про мобильные приложения, что, несомненно, приятно. Эта область новая и интересная для разработчиков и исследователей.
Топ-3 багов, найденных за первый год программы:
- Специальной премии удостоилась уязвимость с очень необычным вектором и не сильно сложная в эксплуатации. У нас во многих местах используется comet-сервер для отправки сообщений разного типа по уже открытым соединениям. Эта технология используется и для показа «карандашика» в мессенджере — стандартной индикации того, что вам прямо сейчас на том конце что-то пишут. И именно в этом типе сообщения было неиспользуемое поле, оставшееся со времен отладки, и в него можно было внести произвольные данные. Эти произвольные данные «как есть» передавались тому пользователю, которому вы пишете сообщение. И там обрабатывались как hml. Налицо нетипичная XSS, content spoofing, DDoS и много других «вкусностей», причем жертве не надо ничего делать — только бы был открыт мессенджер. Именно потому, что такую уязвимость можно было применять массово, мы и присудили специальную премию за нее. Быстрый фикс, как вы понимаете, был простым — неиспользуемое поле просто удалили. А затем перепроверили все подобные моменты в других местах.
- Вторая интересная ошибка была в мобильном приложении Badoo на платформе Android. Наши разработчики когда-то обнаружили интересный хак: для ускорения рендеринга использовали собственный обработчик через addJavascriptInterface андроидного API на экранах, использующих веб-вью, который почти ничего не делал, кроме инстанцирования. И в случае MitM-атаки (когда вы не можете полностью доверять приходящим клиенту данным) в этот интерфейс мог попасть JavaScript злоумышленника. Таким образом, на девайсах клиентов мог быть исполнен произвольный код.
- Третий баг (от автора предыдущего бага) заключался в том, что наш собственный загрузчик кеша в Android-приложении недостаточно проверял путь до этого самого кеша. В результате его можно было использовать для получения файлов приложения (ведь загрузчик работает с теми же правами, что и приложение), в том числе и ключи авторизации во внешних системах (например, чтобы авторизоваться через Facebook, «ВКонтакте» и т.д.).
В целом мы считаем, что bounty-программа принесла нам положительный и полезный опыт. Мы ежедневно получаем экспертную оценку наших приложений и сайтов от множества исследователей по всему миру и работаем над улучшением своих продуктов, следя за новостями из области информационной безопасности. Мы высоко ценим доверие наших пользователей и стараемся сделать все, чтобы сохранить безопасность их данных.
Участвуйте в нашей программе, ищите баги на сайтах и в приложениях других компаний. Это очень занимательный процесс, который может не только принести вам положительные эмоции и интересные знания, но и еще и внести существенный вклад в ваш бюджет. Мы платим в фунтах стерлингов, а недавно еще и значительно увеличили суммы премий.
Присылать нам сообщения об уязвимостях или багах лучше всего через платформу Hackerone. Удачного баг-хантинга!
Илья Агеев,
Head of QA, Badoo.
PS: Пока писалась статья, нам в программе на Hackerone сообщили о новых и интересных уязвимостях. О них мы обязательно напишем подробно в следующий раз.