19 сентября получила огласку информация о баге Chrome. Браузер аварийно завершается, если в адресную строку ввести последовательность из 16 символов. В Google уже знают о баге, хотя обнаруживший не получил денежное вознаграждение — это не уязвимость безопасности. Природа ошибки связана с некорректной обработкой нулевого байта. Атаку можно сравнить с похожим случаем, когда Skype после вставки 8 символов ломался полностью: клиент завершался и больше не запускался. Chrome понадобилось 16, ровно в два раза больше.

Баг работает не только в самом браузере Chrome, но и в программах, использующих его движок — это как другие браузеры и сборки Chromium, так и Steam, клиенты мессенджера Slack и так далее. Для падения браузера нужно вставить ссылку в адресную строку, но также сработает наведение указателя мыши на гиперссылку с проблемным кодом. Последний факт уже используют для создания игр, которые наказывают падением браузера.

Комбинация из 16 символов — это http://a/%%30%30. При её вставке в адресную строку или при наведении указателя мыши на гиперссылку, ведущую на неё, происходит следующее:

  • Последовательность в конце ссылки преобразуется в %00, а 0x30 — это ASCII-код для 0. На конце УРЛ появляется нулевой байт.
  • УРЛ передаётся в GURLToDatabaseURL(), которая вызывает ReplaceComponents().
  • УРЛ снова обрабатывается, обнаруживается нулевой байт. Его там быть не должно, поэтому УРЛ помечается как недействительная.
  • Ссылка возвращается GURLToDatabaseURL(), со стороны которой ожидается валидность УРЛ. Происходит вызов spec().
  • УРЛ невалидна. Вызов DCHECK() приводит к падению.

При наведении курсора мыши над проблемной гиперссылкой происходит примерно то же самое, хотя в этом случае УРЛ обрабатывается в другой части браузера. Но и здесь ожидается только корректный адрес.

Вероятно, этот баг скоро исправят, но некоторые пытаются привлечь к нему внимание с помощью небольших игр-демонстраций. Пощекотать себе нервы могут пользователи следующих веб-обозревателей: Google Chrome, Opera, «Яндекс.Браузера» и других хромоподобных браузеров на движке Blink. В Microsoft Edge, Internet Explorer и Mozilla Firefox игры не работают. Перед открытием одной из двух следующих страниц рекомендуется сохранить работу и убедиться в том, что не будут потеряны важные данные.

Первая игра носит название %%30%30. Это лабиринт, созданный обычным HTML-кодом. Он выглядит как веб-страница с кликабельными картинками, по которым нужно провести указатель мыши. Нужно располагать курсор строго над эмодзи с мишками, не натыкаясь на деревья, иначе браузер упадёт. Для пользователей браузеров с иммунитетом: процесс выглядит следующим образом (2,26 МиБ).

https://github.com/szhu/3030/tree/master

Первый пример простой, но скучный. Второй куда более интерактивен и жесток. Это веб-сайт, на котором кликабельная точка гоняется за курсором мыши. Если она его настигнет, то попадёт в фокус, и браузер упадёт. Достижения в игре регистрирует счётчик очков. К недостаткам игры можно отнести низкую скорость движения и предсказуемость поведения «хищника».

http://linkofdeath.com



Описание ошибки на баг-трекере Chromium

Комментарии (40)


  1. alhimik45
    23.09.2015 12:43
    +6

    Для пакмена с одной жизнью неплохо подошло бы


  1. r00tGER
    23.09.2015 12:51
    +8

    Кто сразу же попробовал? :)


  1. vlivyur
    23.09.2015 13:11
    +1

    Vivaldi хорошо падает. Эту вкладку только переоткрывать, иначе ничего в ней не работает.


  1. GavriKos
    23.09.2015 13:46
    +1

    В опере роняется только текущая вкладка. Ее можно без проблем перезагрузить и все будет ок.


    1. N1ghtroad
      23.09.2015 13:59
      +2

      В хроме аналогично. Можно обновлять на F5 и играть дальше.


    1. DaveDee
      23.09.2015 14:52
      +1

      Даже на гитхабе первой игры показан пример с отвалом только вкладки.


  1. Goodkat
    23.09.2015 14:08
    +2

    Ах, вот почему везде вставляют эту ссылку. Думал, это против IE, обращение к дисководу A:

    atomlib: картинки под спойлером загружаются, даже если невидимы.


    1. atomlib
      23.09.2015 14:14

      Спасибо, сделал ту джифку на 2,26 мебибайта ссылкой.


  1. agent10
    23.09.2015 15:22
    +1

    клиенты мессенджера Slack

    Попробовал в Slack просто сообщением — не получается…


  1. pehat
    23.09.2015 15:35
    +1

    Попробовал в ЯБро – пишет «Не удалось отобразить страницу».


  1. roboq6
    23.09.2015 15:44
    +3

    Кстати, в обоих играх можно сжульничать с помощью правой кнопки мыши.

    1.Жмем правую кнопку мыши, появляется контекстное меню. В случае Link of death точка может догнать курсор пока меню открыто, но это не приведет к проигрышу.
    2.Перемещяем курсор куда хотим.
    3.Снова кликаем правой кнопкой мыши, после чего продолжаем игру как ни в чем не бывало.

    Я этому трюку научился еще в flash-играх, забавно что тут он тоже работает.


    1. fshp
      24.09.2015 02:04
      +1

      Сложно как-то. Можно просто курсор вывести за окно браузера.


      1. ivaschenko
        24.09.2015 13:04
        +1

        Счёт не идёт без движения хищника.


        1. fshp
          24.09.2015 13:07
          +1

          Так и при открытом контекстном меню счёт не идёт, даже если двигать мышку.


          1. ivaschenko
            24.09.2015 13:10
            +1

            Можно подвинуть мышку и нажать в новом месте: хищник полетит за вами в новое место, но вы защищены контекстным меню. Но рано или поздно всё равно хищник будет летать быстрее, чем открывается контекстное меню.


            1. fshp
              24.09.2015 13:14
              +1

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


              1. ivaschenko
                24.09.2015 13:16
                +1

                На винде открывает новое одним кликом, да.


  1. roboq6
    23.09.2015 15:51

    image

    Алло, кто-нибудь на хроме видит этот комментарий?


  1. roboq6
    23.09.2015 16:43
    -1

    Внимание, под спойлером картинка которая при открытии в Хроме обрушивает вкладку.
    В качестве источника картинки я указал ту самую ссылку-которую-нельзя-называть.
    Если бы эта картинка загружалась автоматически, то статью было бы невозможно открыть в Хроме.
    Так что дыра не такая безобидная как может показаться на первый взгляд.

    p.s. был вынужден удалить картинку, спойлер не помогает, хром все равно вылетает.


  1. mtp
    23.09.2015 17:55
    -2

    Опера mini под андроидом не падает.


  1. Vlad_IT
    23.09.2015 20:55
    +2

    В инструменте разработчика хрома, если навести на атрибут href элемента, то валится сам инструмент.


  1. Alehandr0
    23.09.2015 22:05
    +1

    Недавно на моём хроме, версии dew-2.0,
    < meta http-equiv=refresh content=100 >
    вызывала непрерывное и постоянное обновление страницы.


  1. Alehandr0
    23.09.2015 22:11

    Недавно на моём хроме, версии dew-2.0,
    < head >
    < meta http-equiv=refresh content=100 >
    < /head >
    вызывала непрерывное и постоянное обновление страницы.


  1. catharsis
    24.09.2015 00:26
    +2

    Странно, что разыменование urlencode происходит два раза.
    Было бы логично, если бы %00 далее оставался последовательностью трех символов


    1. vsespb
      24.09.2015 15:37
      +1

      Вот да. И странно что никто не нашёл способа как это можно использовать в качестве уязвимости.


  1. viruseg
    24.09.2015 04:32
    +1

    В канарейке баг уже пофиксили.


    1. viruseg
      25.09.2015 07:53
      +1

      В стабильной версии тоже.


  1. MrNobody
    24.09.2015 08:14
    +1

    Google Chrome 45.0.2454.93 (64-bit)
    Gentoo
    Падает если вставить в адресную строку весь.
    Если навести на ссылку падает только вкладка.


  1. vintage
    24.09.2015 09:10
    -1

    Давайте похлопаем тому человеку, что десятки лет назад придумал null terminated string и всем тем миллионам разработчиков, что до сих пор не выпилили эту гадость из своих проектов.


    1. Elvish
      24.09.2015 09:56
      +1

      а как Вы предлагаете хранить длину строки? или сделать все строки фиксированного размера? Или вообще все символы связным списком?
      Если хранить длину — то в скольких битах? Тут или перерасход или недостаток рано или поздно случится. Если сделать переменное число бит на хранение длины строки — то оверхед будет при считывании этой длины.
      Интересует именно универсальный и кросс платформенный подход.
      И оценочное сравнение по потреблению лишней памяти для мелких и больших строк. А также сравнение производительности в типичных операциях со строками.


      1. Alexey2005
        24.09.2015 10:27

        Похоже, что null-terminated-строки — действительно худший способ хранения строк из всех известных человечеству. Во-первых, он крайне не производителен. Ведь большинство операций со строками требует предварительного определения их длины, а для этого вам придётся пробежать всю строку в поисках нуля. Например, если вы копируете строку — вы должны сначала подсчитать её длину, а потом пробежать по ней повторно, уже для собственно копирования. Разве не оверхед?
        Во-вторых, на строки сразу же накладывается ограничение — они не смогут содержать символ null. И тут начинаются проблемы: всякое там экранирование, преобразование и прочие хитрые схемы.
        Наконец, длина любой строки всё равно обязана где-то храниться. Ведь мы же выделяем под неё память? И эту память сборщик мусора потом будет должен как-то освободить. Естественно, он должен знать размер освобождаемого блока. А значит, размер блока памяти со строкой всё одно где-то лежит. Просто в неявном виде. Ну и что это за гениальный приём — хранить длину строки, но не использовать, вместо этого занимаясь постоянными поисками нуля?


        1. splav_asv
          24.09.2015 11:24
          +1

          Null-terminated строки живут только в мире без GC, в случае наличия GC их используют только для ffi в C.
          Если в языке нет объектов, передавать везде два параметра видимо очень не хотелось. Похоже такой способ хранения обусловлен системой типов языка C.
          А в остальном мире — есть native строки в соответствующих языках, ими и следует пользоваться…


          1. Bronx
            30.09.2015 10:54
            +1

            Не обязательно передавать два параметра. BSTR, например, передаётся как обычный указатель на null-terminated строку и отлично совместим с С, но хранит длину строки по отрицательному смещению.


      1. vintage
        25.09.2015 19:03
        +1

        Так же как и любые другие массивы — длина массива (4-8 байт), после которой идут элементы. Символы обычно хранятся в UCS-2 кодировке (2 байта на символ), реже в UCS-4 (4 байта на символ), так что на этом фоне затраты на хранение длины строки — незначительны.


  1. Didjeru
    30.09.2015 18:19

    Your score is: 2648 вроде ничего не падает. Минт, хромиум…