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

Posted

技术标签:

【中文标题】用不同的代码替换 MicrosoftAjax.js 文件中的 eval()【英文标题】:Replacing eval() in MicrosoftAjax.js file with different code 【发布时间】:2021-10-07 19:01:28 【问题描述】:

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

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

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

【问题讨论】:

取决于您对“有限更改”的定义 - 因为,如果没有 MicrosoftAjax.js,您将无法加载服务 .js 资源 - 这意味着编写一种替代方法来发出请求等 - 但是,该文件中的大部分 eval 都可以重写 - 只有一个我不确定是 Array.parse 的那个 - 但无论如何看起来都没有使用 Array.parse 理论上可以重写为JSON.parse - 所以,真的,你可以重写它,删除eval('debugger') 的那个 - 只是意味着不会调用调试器,而另一个三,Type.parseSys.Net._WebRequestManager.prototype 中的重写也相当简单 - 留下 Sys.Serialization.JavaScriptSerializer.deserialize 中处理日期的那个,这可能是一个问题 - 但是,可以用 JSON.parse 替换为 @ 987654331@ 处理 WCF 中的奇数日期格式 当然,我假设我知道您使用的是哪个版本的 MicrosoftAjax.js @Bravo :谢谢,我看到有 5 个对 eval() 函数的引用。我对替换这些引用有点不自信,因为我对 JavaScript 还很陌生。 您使用的是哪个版本的 MicrosoftAjax.js? 【参考方案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+)(?:[+-]\d4|)\)\/$/);
                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(在我们网站的其余部分使用,该文件作为公共标头的一部分加载),没有任何问题也有 - 然后我什至尝试更改全局公共部分,并且生产站点没有跳过一个节拍。

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

【讨论】:

非常感谢,让我试试这些更改,看看它是否有效! @DotNetSpartan - 如果您的文件与https://ajax.aspnetcdn.com/ajax/4.5.2/1/MicrosoftAjax.js 相同,那么您应该很好

以上是关于用不同的代码替换 MicrosoftAjax.js 文件中的 eval()的主要内容,如果未能解决你的问题,请参考以下文章

没有 MicrosoftAjax.js 和 MicrosoftMvcAjax.js 的 ASP.NET MVC

MVC Ajax Helpers

用不同的替换替换多个正则表达式匹配

perl:用不同大小的图案替换图案

如何调用webservice

dreamweaver 里面怎么用正则表达批量替换下面代码?