mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-07 22:01:24 +00:00
fix: harden exec allowlist parsing
This commit is contained in:
@@ -585,6 +585,11 @@ export type ExecCommandAnalysis = {
|
||||
};
|
||||
|
||||
const DISALLOWED_PIPELINE_TOKENS = new Set([">", "<", "`", "\n", "\r", "(", ")"]);
|
||||
const DOUBLE_QUOTE_ESCAPES = new Set(["\\", '"', "$", "`", "\n", "\r"]);
|
||||
|
||||
function isDoubleQuoteEscape(next: string | undefined): next is string {
|
||||
return Boolean(next && DOUBLE_QUOTE_ESCAPES.has(next));
|
||||
}
|
||||
|
||||
type IteratorAction = "split" | "skip" | "include" | { reject: string };
|
||||
|
||||
@@ -637,6 +642,21 @@ function iterateQuoteAware(
|
||||
continue;
|
||||
}
|
||||
if (inDouble) {
|
||||
if (ch === "\\" && isDoubleQuoteEscape(next)) {
|
||||
buf += ch;
|
||||
buf += next;
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
if (ch === "$" && next === "(") {
|
||||
return { ok: false, reason: "unsupported shell token: $()" };
|
||||
}
|
||||
if (ch === "`") {
|
||||
return { ok: false, reason: "unsupported shell token: `" };
|
||||
}
|
||||
if (ch === "\n" || ch === "\r") {
|
||||
return { ok: false, reason: "unsupported shell token: newline" };
|
||||
}
|
||||
if (ch === '"') {
|
||||
inDouble = false;
|
||||
}
|
||||
@@ -749,6 +769,12 @@ function tokenizeShellSegment(segment: string): string[] | null {
|
||||
continue;
|
||||
}
|
||||
if (inDouble) {
|
||||
const next = segment[i + 1];
|
||||
if (ch === "\\" && isDoubleQuoteEscape(next)) {
|
||||
buf += next;
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
if (ch === '"') {
|
||||
inDouble = false;
|
||||
} else {
|
||||
@@ -1067,6 +1093,7 @@ function splitCommandChain(command: string): string[] | null {
|
||||
|
||||
for (let i = 0; i < command.length; i += 1) {
|
||||
const ch = command[i];
|
||||
const next = command[i + 1];
|
||||
if (escaped) {
|
||||
buf += ch;
|
||||
escaped = false;
|
||||
@@ -1085,6 +1112,12 @@ function splitCommandChain(command: string): string[] | null {
|
||||
continue;
|
||||
}
|
||||
if (inDouble) {
|
||||
if (ch === "\\" && isDoubleQuoteEscape(next)) {
|
||||
buf += ch;
|
||||
buf += next;
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
if (ch === '"') {
|
||||
inDouble = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user