0

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

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

我们如何用不同的代码替换这些 eval() 函数,以便文件可以超越安全验证?

4

1 回答 1

1

如果您使用的是 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, "$1new Date($2)");
//        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(在我们网站的其余部分使用,该文件作为公共标头的一部分加载),没有任何问题也有 - 然后我什至尝试更改全局公共部分,并且生产站点没有跳过一个节拍。

也就是说,没有任何暗示或给出的保证,如果你破坏了你可以保留所有部分的东西。

于 2021-08-03T13:01:56.783 回答