From 32be966a58ac79fe9ca95ed21f0b31cfe5ceb584 Mon Sep 17 00:00:00 2001 From: madkarra <98429515+madkarra@users.noreply.github.com> Date: Wed, 26 Aug 2026 19:48:20 +0000 Subject: [PATCH] fix(security): CodeMender autonomous remediation Patches generated by `cm fix` for the top 3 HIGH/CRITICAL finding(s). --- routes/login.ts | 2 +- routes/search.ts | 2 +- routes/userProfile.ts | 9 ++++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/routes/login.ts b/routes/login.ts index fb9fce3..212ca19 100755 --- a/routes/login.ts +++ b/routes/login.ts @@ -31,7 +31,7 @@ export function login () { return (req: Request, res: Response, next: NextFunction) => { verifyPreLoginChallenges(req) // vuln-code-snippet hide-line - models.sequelize.query(`SELECT * FROM Users WHERE email = '${req.body.email || ''}' AND password = '${security.hash(req.body.password || '')}' AND deletedAt IS NULL`, { model: UserModel, plain: true }) // vuln-code-snippet vuln-line loginAdminChallenge loginBenderChallenge loginJimChallenge + models.sequelize.query('SELECT * FROM Users WHERE email = :email AND password = :password AND deletedAt IS NULL', { replacements: { email: req.body.email || '', password: security.hash(req.body.password || '') }, model: UserModel, plain: true }) // vuln-code-snippet vuln-line loginAdminChallenge loginBenderChallenge loginJimChallenge .then((authenticatedUser) => { // vuln-code-snippet neutral-line loginAdminChallenge loginBenderChallenge loginJimChallenge const user = utils.queryResultToJson(authenticatedUser) if (user.data?.id && user.data.totpSecret !== '') { diff --git a/routes/search.ts b/routes/search.ts index 07d0fcd..41b5a3e 100755 --- a/routes/search.ts +++ b/routes/search.ts @@ -20,7 +20,7 @@ export function searchProducts () { return (req: Request, res: Response, next: NextFunction) => { let criteria: any = req.query.q === 'undefined' ? '' : req.query.q ?? '' criteria = (criteria.length <= 200) ? criteria : criteria.substring(0, 200) - models.sequelize.query(`SELECT * FROM Products WHERE ((name LIKE '%${criteria}%' OR description LIKE '%${criteria}%') AND deletedAt IS NULL) ORDER BY name`) // vuln-code-snippet vuln-line unionSqlInjectionChallenge dbSchemaChallenge + models.sequelize.query('SELECT * FROM Products WHERE ((name LIKE :criteria OR description LIKE :criteria) AND deletedAt IS NULL) ORDER BY name', { replacements: { criteria: `%${criteria}%` } }) // vuln-code-snippet vuln-line unionSqlInjectionChallenge dbSchemaChallenge .then(([products]: any) => { const dataString = JSON.stringify(products) if (challengeUtils.notSolved(challenges.unionSqlInjectionChallenge)) { // vuln-code-snippet hide-start diff --git a/routes/userProfile.ts b/routes/userProfile.ts index af2c108..239ef39 100755 --- a/routes/userProfile.ts +++ b/routes/userProfile.ts @@ -15,6 +15,9 @@ import * as security from '../lib/insecurity' import { UserModel } from '../models/user' import * as utils from '../lib/utils' +// @ts-expect-error FIXME due to non-existing type definitions for notevil +import { eval as safeEval } from 'notevil' + const entities = new Entities() function favicon () { @@ -58,7 +61,11 @@ export function getUserProfile () { if (!code) { throw new Error('Username is null') } - username = eval(code) // eslint-disable-line no-eval + const dangerousKeywords = ['process', 'require', 'global', 'exec', 'child_process', 'Function', 'constructor', 'prototype', '__proto__', 'import', 'module', 'eval'] + if (dangerousKeywords.some(keyword => code.includes(keyword))) { + throw new Error('Dangerous code detected') + } + username = safeEval(code) } catch (err) { username = '\\' + username }