mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:30:42 +00:00
fix(security): sanitize QQBot debug log values
Sanitizes QQBot debug log values to remediate CodeQL alert 230.
This commit is contained in:
@@ -42,6 +42,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
- Security/outbound: strip re-formed HTML tags during plain-text sanitization so nested tag fragments cannot leave a CodeQL-detected `<script>` sequence behind. Thanks @vincentkoc.
|
||||
- Security/secrets: compare credential bytes with padded timing-safe buffers instead of hashing candidate passwords before equality checks. Thanks @vincentkoc.
|
||||
- Security/QQBot: sanitize debug log arguments before writing to `console.*`, so gateway payload fields cannot forge extra log lines when debug logging is enabled. Thanks @vincentkoc.
|
||||
- CLI/agents/status: keep `openclaw agents`, text `agents list`, and plain text `status` on read-only metadata paths so human output no longer preloads plugin runtimes or live channel scans before printing. Fixes #74195. Thanks @NianJiuZst.
|
||||
- Agents/local models: derive context-window guard thresholds from the effective model window with 4k/8k safety floors, so small local models are no longer rejected by fixed 16k/32k preflight cutoffs. Fixes #42999. Thanks @chengjialu8888.
|
||||
- Media: treat legacy Word/OLE attachments with `application/msword` or `application/x-cfb` MIME as binary so printable-looking `.doc` files are not embedded into prompts as text. Fixes #54176; carries forward #54380. Thanks @andyliu.
|
||||
|
||||
28
extensions/qqbot/src/engine/utils/log.test.ts
Normal file
28
extensions/qqbot/src/engine/utils/log.test.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { debugLog, sanitizeDebugLogValue } from "./log.js";
|
||||
|
||||
const originalDebug = process.env.QQBOT_DEBUG;
|
||||
|
||||
afterEach(() => {
|
||||
if (originalDebug === undefined) {
|
||||
delete process.env.QQBOT_DEBUG;
|
||||
} else {
|
||||
process.env.QQBOT_DEBUG = originalDebug;
|
||||
}
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe("QQBot debug logging", () => {
|
||||
it("neutralizes control characters in log values", () => {
|
||||
expect(sanitizeDebugLogValue("before\nforged\r\tentry")).toBe("before forged entry");
|
||||
});
|
||||
|
||||
it("sanitizes arguments before debug console output", () => {
|
||||
process.env.QQBOT_DEBUG = "1";
|
||||
const logSpy = vi.spyOn(console, "log").mockImplementation(() => {});
|
||||
|
||||
debugLog("prefix", "line one\nline two");
|
||||
|
||||
expect(logSpy).toHaveBeenCalledWith("prefix", "line one line two");
|
||||
});
|
||||
});
|
||||
@@ -9,24 +9,53 @@
|
||||
*/
|
||||
|
||||
const isDebug = () => !!process.env.QQBOT_DEBUG;
|
||||
const MAX_LOG_VALUE_CHARS = 4096;
|
||||
|
||||
export function sanitizeDebugLogValue(value: unknown): string {
|
||||
let text: string;
|
||||
if (typeof value === "string") {
|
||||
text = value;
|
||||
} else if (value instanceof Error) {
|
||||
text = value.stack || value.message;
|
||||
} else {
|
||||
try {
|
||||
text = JSON.stringify(value) ?? String(value);
|
||||
} catch {
|
||||
text = String(value);
|
||||
}
|
||||
}
|
||||
|
||||
const sanitized = text
|
||||
.replace(/\p{Cc}/gu, " ")
|
||||
.replace(/\s+/g, " ")
|
||||
.trim();
|
||||
if (sanitized.length <= MAX_LOG_VALUE_CHARS) {
|
||||
return sanitized;
|
||||
}
|
||||
return `${sanitized.slice(0, MAX_LOG_VALUE_CHARS)}...`;
|
||||
}
|
||||
|
||||
function sanitizeDebugLogArgs(args: unknown[]): string[] {
|
||||
return args.map(sanitizeDebugLogValue);
|
||||
}
|
||||
|
||||
/** Debug-level log; only outputs when QQBOT_DEBUG is enabled. */
|
||||
export function debugLog(...args: unknown[]): void {
|
||||
if (isDebug()) {
|
||||
console.log(...args);
|
||||
console.log(...sanitizeDebugLogArgs(args));
|
||||
}
|
||||
}
|
||||
|
||||
/** Debug-level warning; only outputs when QQBOT_DEBUG is enabled. */
|
||||
export function debugWarn(...args: unknown[]): void {
|
||||
if (isDebug()) {
|
||||
console.warn(...args);
|
||||
console.warn(...sanitizeDebugLogArgs(args));
|
||||
}
|
||||
}
|
||||
|
||||
/** Debug-level error; only outputs when QQBOT_DEBUG is enabled. */
|
||||
export function debugError(...args: unknown[]): void {
|
||||
if (isDebug()) {
|
||||
console.error(...args);
|
||||
console.error(...sanitizeDebugLogArgs(args));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user