From 4c2cb73055c8defa4e094c8a861712f390c8a687 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 7 Mar 2026 19:41:59 +0000 Subject: [PATCH] fix(config): sanitize validation log output to prevent control character injection (#39116) Co-authored-by: Bill --- CHANGELOG.md | 1 + src/config/io.ts | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23eed3c22da..63f350bc3d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -262,6 +262,7 @@ Docs: https://docs.openclaw.ai - Models/provider apiKey persistence hardening: when a provider `apiKey` value equals a known provider env var value, persist the canonical env var name into `models.json` instead of resolved plaintext secrets. (#38889) Thanks @gambletan. - Discord/model picker persistence check: add a short post-dispatch settle delay before reading back session model state so picker confirmations stop reporting false mismatch warnings after successful model switches. (#39105) Thanks @akropp. - Agents/OpenAI WS compat store flag: omit `store` from `response.create` payloads when model compat sets `supportsStore: false`, preventing strict OpenAI-compatible providers from rejecting websocket requests with unknown-field errors. (#39113) Thanks @scoootscooob. +- Config/validation log sanitization: sanitize config-validation issue paths/messages before logging so control characters and ANSI escape sequences cannot inject misleading terminal output from crafted config content. (#39116) Thanks @powermaster888. ## 2026.3.2 diff --git a/src/config/io.ts b/src/config/io.ts index d8b90646d12..586dd9b3227 100644 --- a/src/config/io.ts +++ b/src/config/io.ts @@ -13,6 +13,7 @@ import { shouldDeferShellEnvFallback, shouldEnableShellEnvFallback, } from "../infra/shell-env.js"; +import { sanitizeTerminalText } from "../terminal/safe-text.js"; import { VERSION } from "../version.js"; import { DuplicateAgentDirError, findDuplicateAgentDirs } from "./agent-dirs.js"; import { maintainConfigBackups } from "./backup-rotation.js"; @@ -714,7 +715,10 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) { const validated = validateConfigObjectWithPlugins(resolvedConfig); if (!validated.ok) { const details = validated.issues - .map((iss) => `- ${iss.path || ""}: ${iss.message}`) + .map( + (iss) => + `- ${sanitizeTerminalText(iss.path || "")}: ${sanitizeTerminalText(iss.message)}`, + ) .join("\n"); if (!loggedInvalidConfigs.has(configPath)) { loggedInvalidConfigs.add(configPath); @@ -727,7 +731,10 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) { } if (validated.warnings.length > 0) { const details = validated.warnings - .map((iss) => `- ${iss.path || ""}: ${iss.message}`) + .map( + (iss) => + `- ${sanitizeTerminalText(iss.path || "")}: ${sanitizeTerminalText(iss.message)}`, + ) .join("\n"); deps.logger.warn(`Config warnings:\\n${details}`); }