CDN-провайдер Cloudflare внедрял содержимое памяти своего сервера в код произвольных веб-страниц

    Специалисты по безопасности из Google обнаружили неприятный баг, чем-то похожий на приснопамятную уязвимость Heartbleed в OpenSSL. Она тоже выдаёт любому желающему криптографические ключи, а также куки, пароли, содержимое POST-запросов с личными данными, кредитные карты, ключи API и другое содержимое чужих сессий.

    Здесь уязвимость ограничена всего одним сервис-провайдером, пусть и таким крупным как Cloudflare. Но в определённом смысле этот баг Cloudbleed хуже, чем Heartbleed, потому что утечка данных происходит спонтанно. Эти страницы рутинно скачиваются краулерами, индексируются поисковыми системами, до сих пор хранятся в архивах веб-страниц и в кэше Google.

    Cloudflare является посредником между хостером сайта и посетителями сайта, выполняя роль обратного прокси для веб-сайтов. Из-за ошибки программиста системы Cloudflare на Nginx с сентября 2016 года внедряли случайные фрагменты оперативной памяти своего сервера в содержимое веб-страниц, которое выдавалось всем пользователям.

    Выдача фрагментов оперативной памяти происходила при определённых обстоятельствах. Но если вы заходили на сайт, который обслуживается обратным прокси, то могли получить прямо в браузер вместе с веб-страницей фрагмент чьего-то чужого сетевого трафика.

    Вероятно, для эксплуатации бага нужно было в течение длительного времени массово загружать страницы с сайтов, обслуживаемых Cloudflare, автоматически извлекать приватный трафик и обрабатывать его регулярными выражениями в поисках интересной информации. Это могут быть сессионные ключи, пароли, данные кредитных карт и др.


    Фрагмент сессии некоего случайного пользователя Fitbit, который получили хакеры Project Zero по запросу к Cloudflare

    Среди клиентов Cloudflare — такие клиенты как Uber, OK Cupid и Fitbit (всего пострадали около 4 287 625 доменов, в том числе 2ip.ru, 4pda.ru, avito.ru, diary.ru, forbes.ru, iphones.ru, javascript.ru, prlog.ru, rghost.ru, rosbalt.ru, searchengines.ru). Понятно, что в пользовательских сессиях тех же Uber, OK Cupid и Fitbit передаётся чувствительная информация о поездках пользователей, кредитных картах, маршруты поездок, личные данные о человеке с сайта знакомств, показания фитнес-трекеров и многое другое. Не говоря о миллионах других сайтов, которые сидят на Cloudflare (она контролирует примерно 5% веба, в том числе 11% сайтов из топ-10000). Это как сидеть в ресторане, где одновременно с меню официант подаёт вам часть содержимого кошелька предыдущего клиента.

    Тут не угадаешь, где повезёт, так что эксплуатация предполагает массовое скачивание и обработку информации. Конечно, желательно знать, при каких условиях возникает утечка памяти. Специалистам Google удалось это выяснить случайно в результате рутинной работы по дистилляции (минимизации) корпуса страниц с целью оптимизации фаззинга, которым занимается Google.

    17 февраля 2017 года сотрудник компании Google и известный хакер Тэвис Орманди (Tavis Ormandy) во время минимизации корпуса случайно наткнулся на неожиданные данные. Это был не обычный набор мусора, искажённых или неправильно маркированных данных, а нечто в таком странном формате, что Тэвис Орманди потратил время на дебаггинг, пытаясь выяснить причину ошибки минимизации, то есть ошибку в своём собственном коде. «На самом деле данные были настолько странные, что некоторые мои коллеги из отдела Project Zero тоже заинтересовались, — пишет Тэвис. — Вскоре стало ясно, что мы смотрим на фрагменты неинициализированной памяти, которые перемежаются валидными данными. Загадка разгадалась, потому что эти неинициализированные данные шли от программы, которая как раз поместила в память те данные, которые я указал. Но некоторые окружающие фрагменты имели строки и объекты, которые словно пришли от обратного прокси под управлением Cloudflare — крупнейшего провайдера CDN».

    Так оно и вышло. Чуть позже исследователям удалось воспроизвести баг. Утечка информации происходила при определённом сочетании HTML-тегов на странице, которое вызывало баг на сервере Cloudflare.

    Исследователи поковырялись с багом — и среди нескольких образцов получили ключи шифрования, куки, пароли, фрагменты POST-форм и данные HTTPS-запросов других пользователей. Как только они увидели это, то немедленно прекратили эксплуатацию бага и сразу сообщили о нём в компанию Cloudflare.

    Тэвис Орманди предполагает, что баг Cloudflare связан с функцией ScrapeShield, которая работает у них на серверах — она парсит и обфусцирует HTML. Сама компания Cloudflare позже подтвердила, что проблема действительно была с парсером, который обфусцирует почту, делает Server Side Excludes и Automatic HTTPS Rewrites. Баг закрался примерно год назад, когда этот парсер, написанный на Ragel, оптимизировали и внедрили как модуль Nginx. Теперь выяснилось, что ошибка указателя и перерасход буфера в парсере присутствовали много лет, просто раньше не происходила утечка памяти.

    /* generated code */
    if ( ++p == pe )
        goto _test_eof;

    Вот как парсер из-за бага обрабатывал атрибут в теге <script>.

    script_consume_attr := ((unquoted_attr_char)* :>> (space|'/'|'>'))
    >{ ddctx("script consume_attr"); }
    @{ fhold; fgoto script_tag_parse; }
    $lerr{ dd("script consume_attr failed");
           fgoto script_consume_attr; };

    Орманди говорит, что этот баг хуже Heartbleed в том смысле, что пользователю не нужно совершать целенаправленный запрос, чтобы прочитать фрагмент памяти сервера. Здесь секретная информация принудительно выдаётся в его браузер. Большинство людей просто не поймут, что это такое. Но эти страницы скачиваются краулерами, индексируются поисковыми системами. В случае Heartbleed такой утечки данных не было — там надо было отправлять специальный запрос серверу, где работает OpenSSL.

    Как обычно, через 90 дней Google опубликует информацию из баг-репорта, способ воспроизвести баг и искомое сочетание HTML-тегов, но Cloudflare уже закрыла уязвимость. Хотя они не отреагировали на письма и баг-репорт, но в течение часа заметили призыв Тэвиса в твиттере.


    Сразу нашлись нужные люди из отдела безопасности, которые быстро среагировали. Уязвимость закрыли за 7 часов, а первый фикс выпустили за 47 минут.

    Вчера компания Cloudflare опубликовала отчёт с детальным описанием инцидента. Она сразу предупредила, что утечки пользовательских SSL-ключей не произошло, поскольку SSL-соединения всегда терминируются на изолированной машине с Nginx, которая не была подвержена этому багу.
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 43

      0
      GitLab, Cloudflare, кто следующий?
        +9

        Да кто угодно, от человеческого фактора нет 100% защиты

        +6
        > исключения на стороне сервера
        > Server Side Excludes

        > автоматическую перезапись HTTPS
        > Automatic HTTPS Rewrites is a feature that safely rewrites links to unencrypted resources from HTTP to HTTPS

        Не, я конечно все понимаю что некоторые вещи сложно переводить, но зачем переводить так что вообще смысл полностью утерян?
          0
          поскольку SSL-соединения всегда уничтожаются на изолированной машине с Nginx

          оканчиваются
            0
            кстати, как в трафике оказались такие данные как данные пользовательских карт, если они в нормальной ситуации передаются по SSL соединению а оно завершается у пользователя?
              +1
              SSL-соединение как раз устанавливается между cloudflare и пользователем, иначе этот сервис не мог бы сделать ничего полезного при работе через HTTPS
          • UFO just landed and posted this here
              0
              Вот история от ребят из Гугла: https://bugs.chromium.org/p/project-zero/issues/detail?id=1139
                +1
                В оригинальной статье от CloudFlare написано что в т.ч. были утечки ключей внутренних соединений между CF серверами, но не ключи пользователей.
                One obvious piece of information that had leaked was a private key used to secure connections between Cloudflare machines.
                +3
                Среди клиентов Cloudflare — такие клиенты как Uber, OK Cupid и Fitbit

                Ну вы и сказали, конечно.


                Вот так будет более значимо (ссылка):


                CloudFlare essentially controls 11% of the 10k biggest websites, over 8% of the 100k biggest websites, and almost 5% of sites on the entire web
                  0
                  Так бага в Ragel или в коде который ему скормили?
                    0
                    в коде который ему скормили
                  • UFO just landed and posted this here
                      +5
                      Нельзя_так_просто_взять_и_пропатчить_Ализара.jpg

                      Eще год не прошел, как Ализара патчили последний раз.
                        0

                        Нет, речь идёт о минимизации корпуса для фаззинг-тестирования хрома.


                        Из описания бага:


                        Corpus distillation is a procedure we use to optimize the fuzzing we do by analyzing publicly available datasets. We've spoken a bit about this publicly in the past, for example:

                        https://security.googleblog.com/2011/08/fuzzing-at-scale.html
                        http://taviso.decsystem.org/making_software_dumber.pdf#page=11
                        • UFO just landed and posted this here
                            0

                            Корпус в фаззинге — набор образцов входных данных (на основе которых затем производятся мутации). Для эффективного фаззинга корпус должен покрывать максимальное количество путей в графе потока управления программы, но при этом быть минимального размера.

                            • UFO just landed and posted this here
                              • UFO just landed and posted this here
                                  0

                                  Как минимум в документации к AFL-FUZZ такая терминология используется. А как ещё назвать набор образцов входных данных?

                                  • UFO just landed and posted this here
                                –1
                                Слушайте, вы английский учили в МГИМО, что ли? Смотрим, что нам предлагает тот же Google Translate:

                                имя существительное
                                свод
                                vault, arch, vaulting, dome, corpus, arc
                                тело
                                body, flesh, solid, frame, figure, corpus
                                собрание
                                meeting, assembly, collection, congregation, convention, convocation
                                кодекс
                                code, codex, corpus, lawbook
                                туловище
                                trunk, torso, body, corpus
                                основной капитал
                                fixed capital, capital stock, basic stock, stock, corpus, principal sum

                                Неужели нельзя на основании этого набора значений выдать какое-то удобоваримое и понятное русскому уху?
                                  –1

                                  Я не знаю, где вы учили русский язык, но в нём слово "корпус" в нужном значении есть:


                                  КОРПУС, -а; м. [от лат. corpus — тело]


                                  1. мн.: корпусы, -ов. Совокупность множества каких-л. однородных предметов, образующих целое; массив. Основной к. поэтических текстов.

                                  Большой толковый словарь русского языка.
                                  Гл. ред. С. А. Кузнецов.
                                  Первое издание: СПб.: Норинт, 1998.
                                  Публикуется в авторской редакции 2014 года.

                                    –2
                                    Вы продолжаете издеваться? Я серьезно спрашиваю, где учат английскому так, что слова нужно переводить без контекста и учета их иных значений, под копирку, если вдруг в русском языке есть слово, совпадающее по звучанию/написанию? Возьмите англо-русский словарь ложных друзей переводчика и никогда не пишете больше этой чуши.

                                    И да, слово corpus там тоже есть, как и еще тысяча других, совпадающих по написанию/звучанию с русскими словами, но различающихся по смыслу иногда диаметрально, а иногда просто обладая еще десятком значений. Ну и не путайте латынь и современный английский конечно же.
                                      +1

                                      Ещё раз вам объясняю: в исходном английском посте слово "corpus" используется в значении "набор текстов". В русском языке у слова "корпус" тоже есть такое значение, поэтому я не вижу смысла как-то его переводить.

                                        0

                                        Ну и кроме того, в лингвистике и областях CS, связанных с обработкой текстов, слово "корпус" в таком значении является научным термином, и попытка его перевода была бы просто грубой ошибкой.


                                        Пример: Национальный корпус русского языка


                                        Вам на будущее урок: прежде чем учить кого-то как правильно переводить, ознакомиться с терминологией, принятой в этой области.

                                          0
                                          Принято, приношу извинения. Но тем не менее, на мой взгляд, переводили это какие-то надмозги, любящие англиканизмы. Я не сторонник рассупоневшегося солнышка, но тем не менее. Но возразить и правда нечего, раз корпус это и в русском термин, значит корпус. Правда, стоило тогда бы делать сноски таких терминов.
                                            0

                                            Ну это уж к автору перевода, а не ко мне. Я то как раз пытался объяснить, что это значит.

                                              0
                                              Это понятно, но кто-то прочитает же — мы не в инбоксе ;)
                            +1
                            Так баги были в паре фишек:
                            We quickly identified the problem and turned off three minor Cloudflare features (email obfuscation, Server-side Excludes and Automatic HTTPS Rewrites) that were all using the same HTML parser chain that was causing the leakage. At that point it was no longer possible for memory to be returned in an HTTP response.


                            Далее там не каждый ответ с кодом, а 1 на 3 ляма с копейками. Пофиксили — отлично.
                              +6

                              Вы недооцениваете масштабы проблемы.


                              Вкратце: любые приватные данные, передаваемые через cloudflare (например, залогиненным пользователям), могли утечь другим людям, а так же остаться в любом кэше (гугла, интернет архива, других поисковиков). И да, они там действительно были найдены. И сейчас нет никакой возможности отследить, какие данные утекли. И я далеко не уверен, что кто-то не нашёл это раньше и не собирал это всё втихую.


                              И нет, пострадали не только те сайты, которые использовали «three minor Cloudflare features», пострадали остальные, а в те встраивалось содержимое других сайтов.


                              Это полная задница, если честно.

                                +7

                                Но, собственно, я не особо сильно удивлён этим событием.


                                Сначала доверить свои данные глобальному MitM а потом удивляться, что он, внезапно, кривой и отдаёт ваши данные не только тем, кому положено, но и тем, кому не положено.


                                Сколько раз уже похожее было в других технологиях.


                                  +4

                                  Ещё раз, для непонявших: ваши пароли от digitalocean, coinbase, patreon, news.ycombinator.com, medium, uber, zendesk, 10% других популярных сайтов и 5% остальных интернетов могли оказаться где угодно в публичных данных.

                                    +4
                                    Да прекратите уже это повторять, итак с первого раза тошно стало.
                                      0

                                      Имхо лучше было повторить ещё раз сжато, потому что явно не все понимают, что произошло (см. комментарий от nikitasius чуть выше моего, например), а Cloudflare в своём посте несколько приуменьшили масштабы проблемы (см. цитату из того комментария, например).


                                      Я не думаю, что на данный момент от ещё одного повторения станет тошно достаточному количеству человек, чтобы оправдать отсутствие оповещения тех, кто не понял ещё =).


                                      Точнее (зануда-моуд): я думаю, что пока что польза от того, что так больше человек поймут что случилось и примут соответствующие меры для защиты своих личных данных или сервисов, которыми они управляют, больше, чем вред от того, что другим людям станет тошно от того, что они ещё раз видят повторение описания ситуации.

                                        0
                                        Я не понял, согласится или опровергнуть)

                                        Добавлю лишь от себя, что я нашел свои домены и домены клиентов в списках доменов которые припаркованы на cloudflare и возможно постралали. Но там Cloudflare просто нечего leak, так как как минимум это просто DNS хостинг (уже не nginx, а их ДНС сервера), а как максимум проксирование статики, которая и в африке статика.

                                        Кукисы все идут на домен, где проскирование выключено и используется локальный кеш nginx для динамики.

                                        Следом пароли к аккаунтам: у CF вебморда и кеш-ноды на разных серверах, следовательно (=логично), что пароли в админку CF не были сворованы.

                                        Если я не прав, прошу меня поправить. Так что проблема сильно преувеличена и реально актуальна только для тех, что проксирует весь траффик через CF или использует .example.com куки на поддомены и не контролирует сессии.

                                        Она серьезна, но не для всех.
                                  +1
                                  И за такой баг можно получить всего лишь футболочку согласно bug bounty program. Мотивирует :)
                                    0
                                    Кстати а есть ли юзер френдли сервис куда можно забить список доменов и получить ответ использует ли он cloudflare?
                                    Чтоб пользователям было удобно выяснять от каких сервисов пароли менять.
                                    0
                                    Похоже их корневой сертификат, способный подписать валидными любой домен, свистнули…

                                    Only users with full accounts can post comments. Log in, please.