这是使用Javascript eval()100%安全吗?

时间:2010-12-21 14:38:08

标签: javascript security eval

我正在编写一个生成Javascript代码的PHP库。

Javascript代码包含许多名为component001component002等的组件。

页面是通过AJAX动态加载的。

我需要通过URL变量传递组件的名称,然后由脚本evaled()。

我保护正在被唤醒的东西的唯一方法是使用正则表达式^component[0-9]{3}$:如果它通过则会被撤消,否则就不会。

对我来说这是100%安全的,因为没有任何东西会被执行,除非它只是我已知组件之一的名称,或者是否有关于eval()命令的内容可以在此代码中被利用样品,例如正则表达式注入,某种跨站点脚本等?

window.onload = function() {

    // *** DEFINED IN ANOTHER JAVASCRIPT FILE:
    var component001 = 'testing111';
    var component002 = 'testing222';
    var component003 = 'testing333';

    var APP = {};

    APP.getUrlVars = function() {
        var vars = [], hash;
        var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
        for(var i = 0; i < hashes.length; i++) {
            hash = hashes[i].split('=');
            vars.push(hash[0]);
            vars[hash[0]] = hash[1];
        }
        return vars;
    }

    APP.getUrlVar = function(name, defaultValue) {
        defaultValue = (typeof defaultValue == 'undefined') ? '' : defaultValue;
        var vars = APP.getUrlVars();
        if(vars[name] === undefined)
        {
            return defaultValue;
        } else {
            return vars[name];
        }
    }

    APP.safeEval = function(nameOfComponent) {
        var REGEX_VALID_NAME = /^component[0-9]{3}$/;
        if(REGEX_VALID_NAME.test(nameOfComponent)) {
            return eval(nameOfComponent);
        } else {
            return 'ERROR';
        }

    }

    // *** JAVASCRIPT FILE LOADED VIA AJAX:

    var nameOfComponentToDisplay = APP.getUrlVar('compname', 'component001');
    var component = APP.safeEval(nameOfComponentToDisplay);
    document.write(component);

}

3 个答案:

答案 0 :(得分:15)

使用eval几乎没有理由,我认为这不是其中之一。请记住,所有对象都像字典一样,所以你可以简单地做这样的事情:

var components = {
    component001 : 'testing111',
    component002 : 'testing222',
    component003 : 'testing333'
};

APP.safeEval = function(nameOfComponent) {
    var result = components[nameOfComponent];
    if(result) {
        return result;
    } else {
        return 'ERROR';
    }
}

答案 1 :(得分:4)

好吧,如果有一个名字,那么

  eval(component101)

无论如何都不会做任何事情,所以看起来很安全。也许你的意思是

  return eval(nameOfComponent + '()');

如果是这样,那么我不明白你为什么不把你的组件放在命名空间对象中。那么你根本不需要eval:

  return components[nameOfComponent]();

如果它们不是功能,那么同样的事情也适用,但是你要离开“()”。

答案 2 :(得分:3)

如果变量在另一个javascript文件中定义并且只包含数字和字母,那么它们就是全局命名空间的一部分。因此,可以将它们作为window对象的属性进行访问(不需要eval!):

if (typeof window[nameOfComponent] !== 'undefined')
    return window[nameOfComponent]
return 'ERROR';