Code injection: request input passed to eval
eval runs whatever string it is given as code. When that string comes from a request, the person sending the request decides what your server executes.
Example
app.post("/contributions", (req, res) => {
const preTax = eval(req.body.preTax);
const roth = eval(req.body.roth);
save(preTax, roth);
});app.post("/contributions", (req, res) => {
const preTax = Number.parseInt(req.body.preTax, 10);
const roth = Number.parseInt(req.body.roth, 10);
if (![preTax, roth].every(Number.isFinite)) return res.sendStatus(400);
save(preTax, roth);
});How it happens
Developers reach for eval to turn "42" into 42 or to evaluate a formula. But a value of require('child_process').execSync('id') is also valid JavaScript. The same applies to new Function, vm.runInNewContext, setTimeout with a string, and template engines asked to compile user-supplied template text. OWASP NodeGoat ships exactly this bug in its contributions form.
How to fix it
There is almost never a reason to evaluate request data.
- Parse numbers with Number or parseInt and validate them
- Use JSON.parse for structured data
- For behaviour chosen by the user, dispatch through a table of allowed operations
- Render fixed templates and pass user data only as variables
How RepoVerse finds it
- CriticalRequest input is executed as code
Whoever sends the request chooses what JavaScript runs on the server, with the process's permissions — read files, reach the database, open a shell.
data flow · CWE-95
- HighCode evaluated from a value
`eval`, `exec` or `new Function` is called on something that is not a literal.
pattern
- HighRequest input chooses or compiles a template
Template engines evaluate expressions; user-controlled template text or view names can lead to code execution or file disclosure.
data flow · CWE-1336
Questions
- Is eval safe if I validate the input first?
- Validation that is strict enough to make eval safe is strict enough to replace eval with a parser. Remove eval instead.
- What severity is code injection?
- Critical. It gives the attacker code execution with the server process's permissions, which usually means the database, the secrets in the environment and the machine itself.
Related
- Command injection: when a parameter runs a shell commandHow OS command injection (CWE-78) turns a request parameter into a second shell command, the safe execFile pattern, and how to find exec calls fed by user input.
- Insecure deserialization: data that runs as codeWhy deserialising untrusted data with pickle, yaml.load, Java serialization or node-serialize runs attacker code (CWE-502), and the JSON-plus-validation alternative.
- GitHub security scanner for code, secrets and dependenciesScan a GitHub repository for injection flaws, leaked secrets and vulnerable dependencies. Data-flow traces from request to sink, lockfile-aware, with fixes.
Updated 2026-10-11