I'm writing a PHP library which generates Javascript code.
The Javascript code has a number of ponents named ponent001
, ponent002
, etc.
Pages are loaded dynamically via AJAX.
I need to pass the name of the ponent via URL variable which is then evaled() by the script.
The only way I am protecting what is being evaled is with the regular expression ^ponent[0-9]{3}$
: if it passes it gets evaled, otherwise it does not.
To me this is 100% safe since nothing will get executed unless it is simply the name of one of my known ponents, or is there something about the eval()
mand that could be exploited in this code sample, e.g. regex injection, some kind of cross site scripting etc.?
window.onload = function() {
// *** DEFINED IN ANOTHER JAVASCRIPT FILE:
var ponent001 = 'testing111';
var ponent002 = 'testing222';
var ponent003 = '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 = /^ponent[0-9]{3}$/;
if(REGEX_VALID_NAME.test(nameOfComponent)) {
return eval(nameOfComponent);
} else {
return 'ERROR';
}
}
// *** JAVASCRIPT FILE LOADED VIA AJAX:
var nameOfComponentToDisplay = APP.getUrlVar('pname', 'ponent001');
var ponent = APP.safeEval(nameOfComponentToDisplay);
document.write(ponent);
}
I'm writing a PHP library which generates Javascript code.
The Javascript code has a number of ponents named ponent001
, ponent002
, etc.
Pages are loaded dynamically via AJAX.
I need to pass the name of the ponent via URL variable which is then evaled() by the script.
The only way I am protecting what is being evaled is with the regular expression ^ponent[0-9]{3}$
: if it passes it gets evaled, otherwise it does not.
To me this is 100% safe since nothing will get executed unless it is simply the name of one of my known ponents, or is there something about the eval()
mand that could be exploited in this code sample, e.g. regex injection, some kind of cross site scripting etc.?
window.onload = function() {
// *** DEFINED IN ANOTHER JAVASCRIPT FILE:
var ponent001 = 'testing111';
var ponent002 = 'testing222';
var ponent003 = '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 = /^ponent[0-9]{3}$/;
if(REGEX_VALID_NAME.test(nameOfComponent)) {
return eval(nameOfComponent);
} else {
return 'ERROR';
}
}
// *** JAVASCRIPT FILE LOADED VIA AJAX:
var nameOfComponentToDisplay = APP.getUrlVar('pname', 'ponent001');
var ponent = APP.safeEval(nameOfComponentToDisplay);
document.write(ponent);
}
Share
Improve this question
asked Dec 21, 2010 at 14:38
Edward TanguayEdward Tanguay
193k320 gold badges725 silver badges1.1k bronze badges
3
-
4
Instead of using
eval
for this, I'd use the square bracket notation to call your function (e.g.APP[nameOfComponent]();
) – Marcel Korpel Commented Dec 21, 2010 at 14:42 - regex and eval() are both open ended tools that introduce risk. The problem you describe need not embrace that risk. Instead - as @Marcel Korpel and @ChaosPandio have writ - use string matching and function invoking to avoid. – orangepips Commented Dec 21, 2010 at 14:48
-
The only excuse I can think of to use
eval()
is if you're writing something like the Firebug console. As other answers show, most places where you might consider usingeval
can be acheived better without it anyway. And in ihe few remaining scenarios whereeval()
may genuinely be useful, it should certainly not be considered safe. – Spudley Commented Dec 21, 2010 at 14:53
3 Answers
Reset to default 15There is almost zero reasons to use eval
and I think that this is not one of them. Remember that all objects act like dictionaries so you can simply do something like this:
var ponents = {
ponent001 : 'testing111',
ponent002 : 'testing222',
ponent003 : 'testing333'
};
APP.safeEval = function(nameOfComponent) {
var result = ponents[nameOfComponent];
if(result) {
return result;
} else {
return 'ERROR';
}
}
Well, if all there is is a name, then
eval(ponent101)
won't do anything anyway, so it seems safe. Maybe you meant
return eval(nameOfComponent + '()');
If so, then I don't see why you don't just put your ponents in a namespace object. Then you wouldn't need eval at all:
return ponents[nameOfComponent]();
If they're not functions, then the same thing applies, but you'd leave off the "()".
If the variables are defined in another javascript file and contain only numbers and letters, then they are part of the global namespace. As such, they can be accessed as properties of the window
object (no need for eval
!):
if (typeof window[nameOfComponent] !== 'undefined')
return window[nameOfComponent]
return 'ERROR';