security(tts): validate JSON structure when reading TTS user prefs

JSON.parse result was cast directly to TtsUserPrefs without runtime
validation. A tampered or corrupted prefs file could inject
unexpected properties. Add safeParseTtsPrefs() that verifies the
parsed value is a plain object with the expected shape before use.

Fixes #2996
This commit is contained in:
Leszek Szpunar 2026-01-30 13:01:54 +01:00
parent fa9ec6e854
commit 2afe2050b0

View File

@ -353,10 +353,21 @@ export function buildTtsSystemPromptHint(cfg: OpenClawConfig): string | undefine
.join("\n");
}
function safeParseTtsPrefs(raw: string): TtsUserPrefs {
const parsed: unknown = JSON.parse(raw);
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
const obj = parsed as Record<string, unknown>;
const tts = obj.tts;
if (tts !== undefined && (typeof tts !== "object" || tts === null || Array.isArray(tts))) {
return {};
}
return obj as TtsUserPrefs;
}
function readPrefs(prefsPath: string): TtsUserPrefs {
try {
if (!existsSync(prefsPath)) return {};
return JSON.parse(readFileSync(prefsPath, "utf8")) as TtsUserPrefs;
return safeParseTtsPrefs(readFileSync(prefsPath, "utf8"));
} catch {
return {};
}