From bf410350aa9ca81f5e4a1e529f9fd3793cd7f097 Mon Sep 17 00:00:00 2001 From: Patrick Date: Mon, 18 May 2026 16:04:07 -0700 Subject: [PATCH] fix(sast): Authenticated RCE via eval() applied to request body fields preTax/afterTax/roth. The handler passed `req.body.preTax`, `req.body.afterTax`, and `req.body.roth` directly to `eval()`. Because the request body is fully attacker-controlled, any authenticated user could submit a string of JavaScript (e.g. `require('child_process').execSync('...')`) and have it executed in the Node.js server process, resulting in remote code execution. The fix replaces each `eval()` call with `parseInt(..., 10)`, which safely coerces the input to an integer. The existing downstream validations (` --- app/routes/contributions.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/routes/contributions.js b/app/routes/contributions.js index 7f68170b94..cccd91d941 100644 --- a/app/routes/contributions.js +++ b/app/routes/contributions.js @@ -27,11 +27,10 @@ function ContributionsHandler(db) { this.handleContributionsUpdate = (req, res, next) => { - /*jslint evil: true */ - // Insecure use of eval() to parse inputs - const preTax = eval(req.body.preTax); - const afterTax = eval(req.body.afterTax); - const roth = eval(req.body.roth); + // Fix for A1 - SSJS Injection: parse inputs as integers instead of eval() + const preTax = parseInt(req.body.preTax, 10); + const afterTax = parseInt(req.body.afterTax, 10); + const roth = parseInt(req.body.roth, 10); /* //Fix for A1 -1 SSJS Injection attacks - uses alternate method to eval