那天晚上,我亲戚突然问我电脑有没有 IE8,我就说我是 Win10 系统,只能尝试模拟。我猜肯定是他需要在某些市@政单位的网站上操作,结果遇到问题了询问我有没有什么解决方法。事情确实如此,他后面便告诉了我详细情况。

他需要在那个网站上上传自己的个人照片,而这个照片会经过一段脚本的验证,而正常情况下上传内容,浏览器会 alert 一个“浏览器设置有误”的弹窗信息。我就很好奇了,我开启了兼容模式怎么就还说我浏览器有误呢?于是便想到了分析代码的方式,看看这个上传过程中,浏览器都干了些什么事情。

Gov-WebSite-Alert.jpg

经过一段时间后详细的分析,首先在点击上传按钮的时候,它的 onclick 属性运行了一段名为 zpxxdr_sc 的函数。这段函数的整体过程都没有什么问题,但当我把“浏览器设置有误”这个字符串作为条件搜索之后,发现有一段名为 zpxxdr_checkSize 的函数里面出现了它。

再仔细分析这段函数,出现那个错误弹窗的条件主要取决于一个名为 zpxxdr_getFileSize 的函数,它将返回 truefalse 来证明该文件的大小是木有问题的。而这个函数的分析过程则是调用了一个名为 Scripting.FileSystemObject 的 ActiveX 控件,众所周知,现代的浏览器均不支持 ActiveX,所以这个调用了 ActiveX 的函数是主要的问题来源。

既然现代浏览器无法使用 ActiveX,那我们能不能跳过这个验证函数,直接去上传图片呢?我此刻突然发现,这个页面负责上传的 JavaScript 函数均没有做任何封装处理,直接是在网页里面输出了一段又一段的 Script 标签。

借助浏览器的控制台,我们就可以实现该函数的覆盖处理,就可以轻松绕过它的上传检测功能。我自己写了一段和它同名的函数,无论任何条件只返回 true

function zpxxdr_checkSize() {
    return true;
}

执行完之后发现,照片是可以成功上传了!于是就有了今天的这篇博文。可见如果是自己写网站,像这样直接把函数暴露在外的做法是非常不可取的。如果这个网站要替换 ActiveX,用 File 对象的 Size 属性 就可以完美解决。

通过今天的这段经历可以得知,市@政单位的网站技术落后,安全性堪忧。现在都是 9012 年了,还在用 ActiveX 这种过时的技术,我也是深感的佩服。而这还不是重点,关键是它还引用了 JQuery!可见这些代码修修补补了多少回,写程序的人是一点都不用心。

最后附上这段神奇的代码,大家也可以研究一下:

/* 校验文件非空,提交表单跳转导入 */
function zpxxdr_sc() {
    $('#zpxxdr_sc').attr("disabled", true);
    if (CFW.oValid.fnIsNull(uploadForm.FILE.value)) {
        CFW.oTip.fnAlert("请先选择上传文件!");
        $('#zpxxdr_sc').attr("disabled", false);
        return;
    }
    var flag = zpxxdr_checkSize(uploadForm.FILE); // 校验附件大小,不能超过600K
    if (uploadForm.FILE.value.toLocaleLowerCase().substring(uploadForm.FILE.value.lastIndexOf('.') + 1) != 'jpg') {
        CFW.oTip.fnAlert("上传的照片格式必须为jpg");
        $('#zpxxdr_sc').attr("disabled", false);
        return;
    }
    if (flag != true) {
        $('#zpxxdr_sc').attr("disabled", false);
        return false;
    }
    uploadForm.submit();
}

/* 校验文件上传大小 */
function zpxxdr_checkSize(elementObj) {
    if (elementObj.value == "") {
        return true; //空直接返回true
    }
    var file_size = zpxxdr_getFileSize(elementObj);
    if (file_size == null) {
        alert("浏览器设置有误!");
        return false;
    }

    if (file_size == 0) {
        alert("上传的附件不能内容为空");
        return false;
    }

    if (file_size > 600 * 1024) {
        alert("上传的照片不能大于600K");
        return false;
    }
    return true;
};

/* 得到文件上传大小 */
function zpxxdr_getFileSize(elementObj) {
    try {
        var fso, f;
        fso = new ActiveXObject("Scripting.FileSystemObject");
        f = fso.GetFile(elementObj.value);
        var mySize = f.size;
        return mySize;
    } catch(e) {
        return null;
    }
};