用不同的代码替换 MicrosoftAjax.js 文件中的 eval()

Replacing eval() in MicrosoftAjax.js file with different code

我的 Asp.NET WebForm 应用程序中的 HTML/JS .aspx 页面使用 MicrosoftAjax.js 文件,但一些安全策略不允许使用 javascript eval() 函数。他们声称 eval 的所有实例都可以被另一个(希望更安全的)函数替换。

<script src="../../Scripts/MicrosoftAjax.js"></script>

我们如何用不同的代码替换这些 eval() 函数,使文件能够通过安全验证?

如果您使用的是 MicrosoftAjax.js 版本 4.5.2,我可以肯定地说以下内容可能不会破坏任何东西

行号仅供参考 - 查找要替换的具体代码

前两个很简单,单行替换

531行附近

Type.parse = function (typeName, ns) {
    var fn;
    if (ns) {
        fn = Sys.__upperCaseTypes[ns.getName().toUpperCase() + "." + typeName.toUpperCase()];
        return fn || null
    }
    if (!typeName)
        return null;
    if (!Type.__htClasses)
        Type.__htClasses = {};
    fn = Type.__htClasses[typeName];
    if (!fn) {
//replace next line
        fn = eval(typeName);
// with next line
        fn = typeName.split('.').reduce(function(r, v) { return r && r[v]; }, window);
//
        Type.__htClasses[typeName] = fn
    }
    return fn
};

662行左右

Array.parse = function (value) {
    if (!value)
        return [];
    // replace next line
    return eval(value)
    // with next line
    return JSON.parse(value)
};

下一篇只需注释掉如图所示的行

830行附近

    fail: function (message) {
        this._appendConsole(message);
// comment out the next two lines
        //if (Sys.Browser.hasDebuggerStatement)
        //    eval("debugger")
    },

您可以完全评论或删除下一个功能

2448行附近

// comment out this whole function
//Sys.Serialization.JavaScriptSerializer.deserialize = function (data, secure) {
//    if (data.length === 0)
//        throw Error.argument("data", Sys.Res.cannotDeserializeEmptyString);
//    try {
//        var exp = data.replace(Sys.Serialization.JavaScriptSerializer._dateRegEx, "new Date()");
//        if (secure && Sys.Serialization.JavaScriptSerializer._jsonRegEx.test(exp.replace(Sys.Serialization.JavaScriptSerializer._jsonStringRegEx, "")))
//            throw null;
//        return eval("(" + exp + ")")
//    } catch (a) {
//        throw Error.argument("data", Sys.Res.cannotDeserializeInvalidJson)
//    }
//};

需要更换get_object方法

3938行左右

// replace this function
    get_object: function () {
        if (!this._resultObject)
            this._resultObject = Sys.Serialization.JavaScriptSerializer.deserialize(this.get_responseData());
        return this._resultObject
    },
// with this function
    get_object: function () {
        if (!this._resultObject) {
            this._resultObject = JSON.parse(this.get_responseData(), function wcfReviver(key, value) {
                if (typeof value !== "string") {
                    return value;
                }
                var d = value.match(/^\/Date\((-?\d+)(?:[+-]\d{4}|)\)\/$/);
                return d && d.length === 2 ? new Date(+d[1]) : value;
            });
        }
        return this._resultObject
    },

还有另一个简单的单行替换

4166行附近

    executeRequest: function (webRequest) {
        var executor = webRequest.get_executor();
        if (!executor) {
            var failed = false;
            try {
// replace next line
                var executorType = eval(this._defaultExecutorType);
// with next line
                var executorType = this._defaultExecutorType.split('.').reduce(function(r, v) { return r && r[v]; }, window);
// 
                executor = new executorType
            } catch (a) {
                failed = true
            }
            webRequest.set_executor(executor)
        }
        if (executor.get_aborted())
            return;
        var evArgs = new Sys.Net.NetworkRequestEventArgs(webRequest),
        handler = this._get_eventHandlerList().getHandler("invokingRequest");
        if (handler)
            handler(this, evArgs);
        if (!evArgs.get_cancel())
            executor.executeRequest()
    }

我可以确认我将这些更改应用于开发测试站点,并且它一直在工作。我什至将它应用到站点的生产版本中,用于一个很少使用的部分,出于某种原因专门加载 MicrosoftAjax.js(在我们站点的其余部分使用中,此文件作为公共 [=51= 的一部分加载) ]),那里也没有任何问题 - 然后我什至尝试更改全局公共部分,并且生产站点没有跳过任何一个节拍。

也就是说,没有任何暗示或给出的保证,如果您弄坏了某样东西,您可以保留所有碎片。