移动运营商 Javascript 注入

信息安全 javascript
2021-09-02 20:35:18

因此,英国的 T-Mobile 似乎正在将一个 javascript 文件注入到通过其移动数据网络传输的文件的头部。

有问题的文件是 1.2.3.8/bmi-int-js/bmi.js (内容如下)

我的问题是这个

如何防御(应用程序/网站)免受这样的运营商注入攻击?

我谨慎地使用攻击这个词,因为我确信他们会声称他们没有做任何邪恶的事情,并且它实际上是用来加速移动网络上的交付,但它是:

  1. 打破javascript左右和中心。
  2. 使您的服务器看起来像是被黑了 - 直到您注意到 URL 的 1.2.3.8/ 部分
  3. 阻止您的应用程序/网站工作

我有基于 jQuery 的应用程序,它最简单的形式是http://twitter.github.com/bootstrap javascript 插件。

以下 bmi 文件中的代码:

Editnote:下面编辑的代码带有缩进和换行符是可读的。

var bmi_htmlEdit = 0;
var bmi_ie;
var bmi_ns;
var bmi_safari;
var bmi_imageObjSelected;
var bmi_ffx_op_toolTip = "Shift+R improves the quality of this image. Shift+A improves the quality of all images on this page.";
var bmi_toolTip = "Shift+R improves the quality of this image. CTRL+F5 reloads the whole page.";
var bmi_ns_tooltip = "Shift+Reload reloads the whole page.";
var bmi_toolTipSeperator = " ... ";
var bmi_concatStr = "bmi_orig_img";
var bmi_frameNotAllowed;
var agt = navigator.userAgent.toLowerCase();
var is_major = parseInt(navigator.appVersion);
var is_minor = parseFloat(navigator.appVersion);
var bmi_ns = ((agt.indexOf('mozilla') != -1) && (agt.indexOf('spoofer') == -1) && (agt.indexOf('compatible') == -1) && (agt.indexOf('opera') == -1) && (agt.indexOf('webtv') == -1) && (agt.indexOf('hotjava') == -1));
var bmi_ns2 = (bmi_ns && (is_major == 2));
var bmi_ns3 = (bmi_ns && (is_major == 3));
var bmi_ns4 = (bmi_ns && (is_major == 4));
var bmi_ns4up = (bmi_ns && (is_major >= 4));
var bmi_nsonly = (bmi_ns && ((agt.indexOf(";nav") != -1) || (agt.indexOf("; nav") != -1) || (agt.indexOf("Netscape") != -1) || (agt.indexOf("netscape") != -1)));
var bmi_ns6 = (bmi_ns && (is_major == 5));
var bmi_ns6up = (bmi_ns && (is_major >= 5));
var is_gecko = (agt.indexOf('gecko') != -1);
var bmi_firefox = (agt.indexOf('firefox') != -1);
var bmi_safari = (agt.indexOf('applewebkit') != -1);
var bmi_ie = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
var bmi_ie3 = (bmi_ie && (is_major < 4));
var bmi_ie4 = (bmi_ie && (is_major == 4) && (agt.indexOf("msie 4") != -1));
var bmi_ie4up = (bmi_ie && (is_major >= 4));
var bmi_ie5 = (bmi_ie && (is_major == 4) && (agt.indexOf("msie 5.0") != -1));
var bmi_ie5_5 = (bmi_ie && (is_major == 4) && (agt.indexOf("msie 5.5") != -1));
var bmi_ie5up = (bmi_ie && !bmi_ie3 && !bmi_ie4);
var bmi_ie5_5up = (bmi_ie && !bmi_ie3 && !bmi_ie4 && !bmi_ie5);
var bmi_ie6 = (bmi_ie && (is_major == 4) && (agt.indexOf("msie 6.") != -1));
var bmi_ie6up = (bmi_ie && !bmi_ie3 && !bmi_ie4 && !bmi_ie5 && !bmi_ie5_5);
var bmi_opera = (agt.indexOf("opera") != -1);
var bmi_opera2 = (agt.indexOf("opera 2") != -1 || agt.indexOf("opera/2") != -1);
var bmi_opera3 = (agt.indexOf("opera 3") != -1 || agt.indexOf("opera/3") != -1);
var bmi_opera4 = (agt.indexOf("opera 4") != -1 || agt.indexOf("opera/4") != -1);
var bmi_opera5 = (agt.indexOf("opera 5") != -1 || agt.indexOf("opera/5") != -1);
var bmi_opera5up = (bmi_opera && !bmi_opera2 && !bmi_opera3 && !bmi_opera4);

function bmi_checkAccess(win) {
    bmi_frameNotAllowed = 0;
    window.bmioldOnError = window.onerror;
    window.onerror = null;
    try {
        var l = win.location.href;
    } catch (e) {
        bmi_frameNotAllowed = 1;
    }
    if (bmi_frameNotAllowed == 1) {
        window.onerror = window.bmioldOnError;
        return false;
    } else {
        window.onerror = window.bmioldOnError;
        return true;
    }
}

function bmi_ImageElement(el) {
    if (!el) return 0;
    var str = new String(el.tagName);
    if (str.match("IMG")) {
        return 1;
    }
    if (str.match("INPUT")) {
        if (el.type && bmi_checkInputType(el.type)) {
            return 1;
        }
        return 0;
    }
    if (str.match("OBJECT")) {
        if (el.type && bmi_checkMIMEType(el.type)) {
            el.bmi_objTag = 1;
            return 1;
        }
    }
    if (str.match("EMBED")) {
        if (el.type && bmi_checkMIMEType(el.type)) {
            return 1;
        }
    }
    if (str.match("AREA") || str.match("A")) {
        var p = el.parentNode;
        if (p && (p.tagName == "MAP") && (p.bmi_imgObj != null)) {
            el.bmi_mapImage = p.bmi_imgObj;
            p.bmi_imgObj.bmi_areaEl = el;
            return 1;
        }
    }
    return 0;
}

function bmi_resetTitle(el) {
    if (!el) return;
    if (el.bmi_touched != 1) return;
    el.title = "";
    if (el.bmi_oldTitle) {
        el.title = el.bmi_oldTitle;
        if (el.bmi_oldAlt) {
            el.alt = el.bmi_oldAlt;
        }
    } else if (el.bmi_oldAlt) {
        el.alt = el.bmi_oldAlt;
        if (bmi_ie) el.title = el.alt;
    }
    if (el.bmi_gotOriginal) {
        if (el.bmi_orig_mouseout) {
            el.onmouseout = el.bmi_orig_mouseout;
        }
    }
}

function bmi_checkElement(el) {
    var pwindow = null;
    if (el.bmi_gotOriginal) return;
    if (el.bmi_mapImage) {
        if (el.bmi_mapImage.bmi_gotOriginal == 1) {
            el.bmi_gotOriginal = 1;
            if (el.bmi_touched) bmi_resetTitle(el);
            return;
        }
    }
    if (el.bmi_touched != 1) {
        bmi_setElementTitle(el);
        if (el.onmouseout) {
            el.bmi_orig_mouseout = el.onmouseout;
            el.onmouseout = bmi_safeMouseOutEvents;
        } else {
            el.onmouseout = bmi_safeMouseOutEvents;
        }
    } else {
        el.title = el.bmi_title;
        el.alt = el.bmi_alt;
    }
    if (el.bmi_mapImage) bmi_imageObjSelected = el.bmi_mapImage;
    else bmi_imageObjSelected = el;
    if (bmi_ie || bmi_opera) pwindow = document.parentWindow;
    else if (bmi_nsonly || is_gecko) pwindow = document.defaultView;
    else pwindow = null;
    if (pwindow && (pwindow != pwindow.parent)) {
        pwindow.focus();
        el.bmi_changedFocus = 1;
    }
    return;
}

function bmi_setElementTitle(el) {
    var tmpAlt = "";
    if (el.alt) {
        tmpAlt = el.alt;
        el.bmi_oldAlt = el.alt;
        el.bmi_alt = "";
        el.alt = "";
    }
    if (el.title) {
        el.bmi_oldTitle = el.title;
        el.title = el.title + "";
    } else {
        el.title = tmpAlt + "";
    }
    if (bmi_firefox) {
        el.title = el.title + bmi_toolTipSeperator + bmi_ffx_op_toolTip;
        el.bmi_touched = 1;
        el.bmi_title = el.title;
    } else if (bmi_opera || bmi_safari) {
        el.title = bmi_ffx_op_toolTip;
        el.bmi_touched = 1;
        el.bmi_title = el.title;
    } else {
        el.title = el.title + bmi_toolTipSeperator + bmi_toolTip;
        el.bmi_touched = 1;
        el.bmi_title = el.title;
    }
    return;
}

function bmi_checkInputType(type) {
    if (!type) return 0;
    if (type.match("image") || type.match("Image")) {
        return 1;
    }
    return 0;
}

function bmi_checkMIMEType(type) {
    var typeStr = new String(type);
    var find = /image\//gi;
    if (typeStr.search(find) != -1) return 1;
    return 0;
}

function bmi_mouseOver(e) {
    bmi_imageObjSelected = null;
    var obj;
    if (document.bmi_onmouseover_original != null) document.bmi_onmouseover_original(e);
    if (bmi_ie || bmi_opera) {
        var e = window.event;
        obj = e.srcElement;
    } else {
        obj = e.target;
    }
    if (obj.bmi_gotOriginal) return;
    if (bmi_ImageElement(obj)) {
        bmi_checkElement(obj);
    }
    return;
}

function bmi_safeMouseOutEvents(e) {
    var obj;
    if (bmi_ie || bmi_opera) {
        e = window.event;
        obj = e.srcElement;
    } else {
        obj = e.target;
    }
    bmi_resetTitle(obj);
    if (obj.bmi_changedFocus == 1) {
        var pwindow = null;
        if (bmi_ie || bmi_opera) pwindow = document.parentWindow;
        else if (bmi_nsonly || is_gecko) pwindow = document.defaultView;
        else pwindow = null;
        if (pwindow) {
            pwindow.top.focus();
            obj.bmi_changedFocus = 0;
        }
    }
    if (obj.bmi_orig_mouseout) {
        obj.bmi_orig_mouseout();
    }
}

function bmi_updateImageSrc(src) {
    var found = 0;
    var find = /\?/g;
    var editUrl;
    var editIndex;
    var editProto;
    var bmiSignIndex;
    var bmiSign;
    srcString = new String(src);
    if (srcString.search(find) != -1) {
        found = 1;
        srcString = srcString.concat("&" + bmi_concatStr + "=1");
    } else {
        var i = srcString.lastIndexOf("/");
        var newStr = srcString.substring(i + 1);
        srcString = srcString.concat("/" + bmi_concatStr + "/" + newStr);
    }
    if (bmi_htmlEdit) {
        editIndex = srcString.indexOf("://");
        if (editIndex != -1) {
            editProto = srcString.substring(0, editIndex + 3);
            editUrl = srcString.substring(editIndex + 3);
            editIndex = editUrl.indexOf("/");
            if (editIndex != -1) {
                editUrl = editUrl.substring(editIndex + 1);
                bmiSignIndex = editUrl.indexOf("/");
                if (bmiSignIndex != -1) {
                    bmiSign = editUrl.substring(0, bmiSignIndex);
                    if (bmiSign == "bmi") {
                        editUrl = editUrl.substring(bmiSignIndex + 1);
                        srcString = editProto + editUrl;
                    }
                }
            }
        }
    }
    return (srcString);
}

function bmi_replaceImages(array) {
    if (!array) return;
    for (var i = 0; i < array.length; i++) {
        if (array[i].bmi_gotOriginal) {
            continue;
        }
        if (array[i].bmi_objTag) {
            array[i].data = bmi_updateImageSrc(array[i].data);
        } else {
            array[i].src = bmi_updateImageSrc(array[i].src);
        }
        array[i].bmi_gotOriginal = 1;
        if (array[i].bmi_touched) {
            bmi_resetTitle(array[i]);
        }
    }
    return;
}

function bmi_replaceInputImages(array) {
    if (!array) return;
    for (var i = 0; i < array.length; i++) {
        if (array[i].bmi_gotOriginal) {
            continue;
        }
        if (array[i].type && bmi_checkInputType(array[i].type)) {
            array[i].src = bmi_updateImageSrc(array[i].src);
            array[i].bmi_gotOriginal = 1;
            if (array[i].bmi_touched) {
                bmi_resetTitle(array[i]);
            }
        }
    }
    return;
}

function bmi_NSlayers() {
    if (document != null) {
        if (!document.layers) {
            bmi_replaceImages(document.tags.IMG);
            bmi_replaceInputImages(document.tags.INPUT);
            return;
        }
        for (var i = 0; i < document.layers.length; i++) {
            bmi_NSlayers(document.layers[i].document);
            bmi_replaceImages(document.layers[i].document.tags.IMG);
            bmi_replaceInputImages(document.layers[i].document.tags.INPUT);
        }
    }
    return;
}

function bmi_downloadAllHandler() {
    if ((true == bmi_checkAccess(parent)) && (parent.location.href != self.location.href)) {
        var newparent = parent;
        do {
            newparent = newparent.parent;
            if ((false == bmi_checkAccess(newparent.parent)) || (newparent.parent.location.href == newparent.location.href)) {
                break;
            }
        } while (newparent); //
        var numFrames = newparent.frames.length;
        var index = 0;
        var frame;
        for (; index < newparent.frames.length; index++) {
            frame = newparent.frames[index];
            if (false == bmi_checkAccess(frame.window)) {
                continue;
            }
            if (frame.window.bmi_reDownloadAllImages) {
                frame.window.bmi_reDownloadAllImages();
            }
        }
        return;
    }
    bmi_reDownloadAllImages();
}

function bmi_reDownloadAllImages() {
    var imgArray;
    var inputArray;
    var backgroundArray;
    var numFrames = window.frames.length;
    var index = 0;
    var frame;
    for (; index < numFrames; index++) {
        frame = window.frames[index];
        if (false == bmi_checkAccess(frame.window)) {
            continue;
        }
        if (frame.window.bmi_reDownloadAllImages) {
            frame.window.bmi_reDownloadAllImages();
        }
    }
    if ((bmi_ie5up || bmi_ns6up || bmi_opera5up || bmi_firefox)) {
        imgArray = document.getElementsByTagName("IMG");
        inputArray = document.getElementsByTagName("INPUT");
        bmi_replaceImages(imgArray);
        bmi_replaceInputImages(inputArray);
    } else if (bmi_ns && (bmi_ns4 || bmi_ns3)) {
        var imgArray;
        var docLayers;
        docLayers = document.layers;
        if (docLayers && docLayers.length) {
            for (var layi = 0; layi < 0; layi++) {
                imgArray = docLayers[layi].document.images;
                bmi_replaceImages(imgArray);
            }
        } else {
            imgArray = document.images;
            bmi_replaceImages(imgArray);
        }
    } else {
        imgArray = document.images;
        bmi_replaceImages(imgArray);
    }
    return;
}

function bmi_reDownloadSelectedImage(img) {
    if (img.bmi_gotOriginal) {
        return;
    }
    if (img && !img.bmi_gotOriginal) {
        if (img.bmi_objTag) {
            img.data = bmi_updateImageSrc(img.data);
        } else {
            img.src = bmi_updateImageSrc(img.src);
        }
        img.bmi_gotOriginal = 1;
        if (img.bmi_touched) {
            bmi_resetTitle(img);
        }
        if (img.bmi_areaEl && (img.bmi_areaEl.bmi_touched)) {
            bmi_resetTitle(img.bmi_areaEl);
            img.bmi_areaEl.bmi_gotOriginal = 1;
        }
    }
    return;
}

function bmi_keypress(e) {
    var reloadSingle = 0;
    var reloadAll = 0;
    var obj;
    if (bmi_ns) {
        if (bmi_ns6up) {
            if ((String.fromCharCode(e.charCode) == 'r') || (String.fromCharCode(e.charCode) == 'R')) reloadSingle = 1;
            else {
                if ((String.fromCharCode(e.charCode) == 'A')) reloadAll = 1;
            }
            obj = e.target;
            var str = new String(obj.tagName);
            if (str.match("INPUT") && (bmi_checkInputType(obj.type) != 1)) {
                if (bmi_imageObjSelected == obj) reloadAll = reloadSingle = 0;
            }
        } else {
            if ((String.fromCharCode(e.which) == 'R') && (e.modifiers == Event.SHIFT_MASK)) reloadSingle = 1;
            else {
                if ((String.fromCharCode(e.which) == 'A') && (e.modifiers == Event.SHIFT_MASK)) reloadAll = 1;
            }
        }
    }
    if (bmi_ie || bmi_opera) {
        if ((String.fromCharCode(window.event.keyCode) == 'R') && (window.event.shiftKey)) reloadSingle = 1;
        else if (bmi_opera) {
            if ((String.fromCharCode(window.event.keyCode) == 'A') && (window.event.shiftKey)) reloadAll = 1;
        }
        var e = window.event;
        obj = e.srcElement;
        var str = new String(obj.tagName);
        if (str.match("INPUT") && (bmi_checkInputType(obj.type) != 1)) {
            if (bmi_imageObjSelected == obj) reloadSingle = reloadAll = 0;
        }
    }
    if (reloadSingle == 1) {
        if (bmi_ns) {
            if (bmi_ns4 || bmi_ns3 || bmi_ns2) {
                return;
            }
        }
        if (bmi_imageObjSelected) bmi_reDownloadSelectedImage(bmi_imageObjSelected);
    } else {
        if (reloadAll == 1) {
            bmi_downloadAllHandler();
        }
    }
    if ((document.bmi_onkeypress_original != null) && (document.bmi_onkeypress_original != bmi_keypress)) {
        return (document.bmi_onkeypress_original(e));
    }
    return;
}

function bmi_linkMapImages(maps, objs) {
    var linked = 0;
    for (var i = 0; i < objs.length; i++) {
        if (linked >= maps.length) {
            return linked;
        }
        if (objs[i].useMap) {
            var newStr = new String(objs[i].useMap);
            var mapName = newStr.substring(newStr.lastIndexOf("#") + 1);
            if (bmi_ImageElement(objs[i]) != 1) continue;
            for (var j = 0; j < maps.length; j++) {
                if (maps[j].name == mapName) {
                    maps[j].bmi_imgObj = objs[i];
                    linked++;
                }
            }
        }
    }
    return linked;
}

function bmi_load() {
    if (bmi_orig_onLoad) {
        bmi_orig_onLoad();
    }
    if (bmi_ns2 || bmi_ns3 || bmi_ns4) {
        window.defaultStatus = bmi_ns_tooltip;
        return;
    }
    if (document.onmouseover) {
        if (document.onmouseover != bmi_mouseOver) {
            document.bmi_onmouseover_original = document.onmouseover;
        }
    }
    document.onmouseover = bmi_mouseOver;
    if (document.onkeypress) {
        if (document.onkeypress != bmi_keypress) {
            document.bmi_onkeypress_original = document.onkeypress;
        }
    } else {
        document.bmi_onkeypress_original = null;
    }
    document.onkeypress = bmi_keypress;
    var maps = document.getElementsByTagName("MAP");
    if ((maps == null) || (maps.length == 0)) {
        return;
    }
    var objs = null;
    if (bmi_ie || bmi_opera) {
        objs = document.all;
        if (objs) {
            bmi_linkMapImages(maps, objs);
        }
    }
    if (bmi_ns || is_gecko) {
        var num = 0;
        objs = document.getElementsByTagName("IMG");
        if (objs) {
            num = num + bmi_linkMapImages(maps, objs);
        }
        if (num >= maps.length) {
            return;
        }
        objs = null;
        objs = document.getElementsByTagName("INPUT");
        if (objs) {
            num += bmi_linkMapImages(maps, objs);
        }
        if (num >= maps.length) {
            return;
        }
        objs = null;
        objs = document.getElementsByTagName("OBJECT");
        if (objs) {
            num += bmi_linkMapImages(maps, objs);
        }
    }
    return;
}
var bmi_orig_onLoad;

function bmi_SafeAddOnload(f, urlStr, htmlEdit) {
    if (urlStr) {
        bmi_concatStr = urlStr;
    }
    if (htmlEdit) {
        bmi_htmlEdit = htmlEdit;
    }
    if (bmi_ie4) {
        window.onload = f;
    } else if (window.onload) {
        if (window.onload != f) {
            bmi_orig_onLoad = window.onload;
            window.onload = f;
        }
    } else {
        window.onload = f;
    }
}
4个回答

我认为这更像是一个编程问题而不是服务器问题,但是......

您不能用于非 SSL/TLS 安全站点。即使那样,根据网络处理流量的方式,您也可能不走运。众所周知,Opera 会将您的流量代理给他们,然后设置从他们的服务器到您的预期目的地的 SSL/TLS 连接。然后,他们能够在代码脱离安全连接后注入代码。

因此,如果有问题的 ISP 正在代理流量,甚至代理 SSL/TLS,您将永远无法阻止他们对该 ISP 的随机用户进行代码注入。如果不是,那么使用 SSL/TLS 将阻止该代码被注入。

您基本上是在问如何防止中间人攻击,但是当中间人是 ISP 并控制基础设施时,这几乎是不可能的。

我已经通过这个相当快,但这些是我能够从中得到的一些东西:

此脚本会降低网站上图像的质量,以减少在移动浏览器上显示页面的加载时间和成本。如果更多网站对移动设备友好,他们就不需要这样做。不幸的是,仍然有很多人没有针对移动设备进行优化。

至于避免这种情况:HTTPS,代理,......

我的同情;这在移动运营商方面有点低俗。防止它的最可靠方法是使用 SSL/TLS(即 HTTPS)。我认为运营商不太可能尝试对 SSL/TLS 流量发起中间人攻击(既是因为社会压力,又因为如果他们这样做,他们会触发所有证书警告在这个地方),所以我认为这应该非常有效。不幸的是,您必须竭尽全力保护流量的完整性。

您可能还对 EFF 的测试您的 ISP项目感兴趣,该项目涉及检测和公开您的 ISP/运营商篡改您的数据包的案例。

您可以使用标准的 HTTP 标头来要求不错的代理不要修改您的 HTTP 流量:

Cache-Control: no-transform

这个特定的代理(可能是ByteMobile)尊重它。

防御此类修改,您必须使用 HTTPS。