Это использование Javascript eval () на 100% безопасно? - PullRequest
4 голосов
/ 21 декабря 2010

Я пишу библиотеку PHP, которая генерирует код Javascript.

В коде Javascript есть несколько компонентов с именами component001, component002 и т. Д.

Страницы загружаются динамически через AJAX.

Мне нужно передать имя компонента через переменную URL, которая затем обрабатывается сценарием.

Единственный способ, которым я защищаю то, что уклоняется, - это регулярное выражение ^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 ]

15 голосов
/ 21 декабря 2010

Существует почти ноль причин для использования eval, и я думаю, что это не одна из них.Помните, что все объекты действуют как словари, поэтому вы можете просто сделать что-то вроде этого:

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

APP.safeEval = function(nameOfComponent) {
    var result = components[nameOfComponent];
    if(result) {
        return result;
    } else {
        return 'ERROR';
    }
}
4 голосов
/ 21 декабря 2010

Ну, если все, что есть, это имя, то

  eval(component101)

ничего не сделает, так что кажется безопасным. Может быть, вы имели в виду

  return eval(nameOfComponent + '()');

Если так, то я не понимаю, почему вы просто не помещаете свои компоненты в объект пространства имен. Тогда вам вообще не понадобится eval:

  return components[nameOfComponent]();

Если они не являются функциями, то применяется то же самое, но вы не указали бы "()".

3 голосов
/ 21 декабря 2010

Если переменные определены в другом файле javascript и содержат только цифры и буквы, то они являются частью глобального пространства имен.Как таковые, они могут быть доступны как свойства объекта window (нет необходимости в eval!):

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