From 750b92f4a3e526cc61fa772e4b19c76af9846a4a Mon Sep 17 00:00:00 2001 From: Manfred Siew Date: Wed, 24 Jun 2026 00:11:03 +0800 Subject: [PATCH 1/2] Potential fix for code scanning alert no. 244: Type confusion through parameter tampering Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- apps/daemon/src/routes/vela.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/apps/daemon/src/routes/vela.ts b/apps/daemon/src/routes/vela.ts index 576fdf66d0c..4f1574a02e6 100644 --- a/apps/daemon/src/routes/vela.ts +++ b/apps/daemon/src/routes/vela.ts @@ -59,11 +59,16 @@ function velaApiProxyBaseUrl(req: Request, getPublicBaseUrl: PublicBaseUrlResolv return `${getPublicBaseUrl(req)}${AMR_API_PROXY_PREFIX}`; } -function velaProxyRequestBody(req: Request): Buffer | null { +function isPlainObject(value: unknown): value is Record { + return Object.prototype.toString.call(value) === '[object Object]'; +} + +function velaProxyRequestBody(req: Request): Buffer | null | undefined { if (req.method === 'GET' || req.method === 'HEAD') return null; if (Buffer.isBuffer(req.body)) return req.body; if (typeof req.body === 'string') return Buffer.from(req.body); if (req.body == null) return null; + if (Array.isArray(req.body) || !isPlainObject(req.body)) return undefined; return Buffer.from(JSON.stringify(req.body)); } @@ -79,6 +84,10 @@ function proxyAmrApiRequest(req: Request, res: Response): void { } const target = new URL(suffix, AMR_API_UPSTREAM_ORIGIN); const body = velaProxyRequestBody(req); + if (body === undefined) { + res.status(400).json({ error: 'invalid_request_body_type' }); + return; + } const streamBody = shouldStreamVelaProxyRequest(req, body); const headers: Record = {}; for (const [key, value] of Object.entries(req.headers)) { From dfd2fa1509d8797d81a9db154d053111868dc1b5 Mon Sep 17 00:00:00 2001 From: Manfred Siew Date: Wed, 24 Jun 2026 00:13:24 +0800 Subject: [PATCH 2/2] Potential fix for code scanning alert no. 243: Type confusion through parameter tampering Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- apps/daemon/src/routes/media.ts | 50 ++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/apps/daemon/src/routes/media.ts b/apps/daemon/src/routes/media.ts index d87a2f81893..2d4232e234b 100644 --- a/apps/daemon/src/routes/media.ts +++ b/apps/daemon/src/routes/media.ts @@ -125,15 +125,19 @@ export function registerMediaRoutes(app: Express, ctx: RegisterMediaRoutesDeps) let task: ReturnType | null = null; try { const taskId = randomUUID(); + const body = + req.body && typeof req.body === 'object' && !Array.isArray(req.body) + ? req.body + : {}; task = createMediaTask(taskId, projectId, { - surface: req.body?.surface, - model: req.body?.model, + surface: body?.surface, + model: body?.model, }); console.error( - `[task ${taskId.slice(0, 8)}] queued model=${req.body?.model} ` + - `surface=${req.body?.surface} ` + - `image=${req.body?.image ? 'yes' : 'no'} ` + - `compositionDir=${req.body?.compositionDir ? 'yes' : 'no'}`, + `[task ${taskId.slice(0, 8)}] queued model=${body?.model} ` + + `surface=${body?.surface} ` + + `image=${body?.image ? 'yes' : 'no'} ` + + `compositionDir=${body?.compositionDir ? 'yes' : 'no'}`, ); const proxyDispatcher = proxyDispatcherRequestInit(process.env, { @@ -146,27 +150,27 @@ export function registerMediaRoutes(app: Express, ctx: RegisterMediaRoutesDeps) projectRoot: PROJECT_ROOT, projectsRoot: PROJECTS_DIR, projectId, - surface: req.body?.surface, - model: req.body?.model, - prompt: req.body?.prompt, - output: req.body?.output, - aspect: req.body?.aspect, + surface: body?.surface, + model: body?.model, + prompt: body?.prompt, + output: body?.output, + aspect: body?.aspect, length: - typeof req.body?.length === 'number' ? req.body.length : undefined, + typeof body?.length === 'number' ? body.length : undefined, duration: - typeof req.body?.duration === 'number' - ? req.body.duration + typeof body?.duration === 'number' + ? body.duration : undefined, - voice: req.body?.voice, - audioKind: req.body?.audioKind, - language: typeof req.body?.language === 'string' ? req.body.language : undefined, - loop: typeof req.body?.loop === 'boolean' ? req.body.loop : undefined, - promptInfluence: typeof req.body?.promptInfluence === 'number' - ? req.body.promptInfluence + voice: body?.voice, + audioKind: body?.audioKind, + language: typeof body?.language === 'string' ? body.language : undefined, + loop: typeof body?.loop === 'boolean' ? body.loop : undefined, + promptInfluence: typeof body?.promptInfluence === 'number' + ? body.promptInfluence : undefined, - compositionDir: req.body?.compositionDir, - image: req.body?.image, - images: Array.isArray(req.body?.images) ? req.body.images : undefined, + compositionDir: body?.compositionDir, + image: body?.image, + images: Array.isArray(body?.images) ? body.images : undefined, onProgress: (line: any) => appendTaskProgress(task, line), requestInit: proxyDispatcher.requestInit, })