mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 12:41:37 +00:00
fix(security): harden inbound metadata sentinel stripping
This commit is contained in:
@@ -102,4 +102,20 @@ describe("stripInboundMetadata", () => {
|
|||||||
This is plain user text`;
|
This is plain user text`;
|
||||||
expect(stripInboundMetadata(input)).toBe(input);
|
expect(stripInboundMetadata(input)).toBe(input);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("does not strip lookalike sentinel lines with extra text", () => {
|
||||||
|
const input = `Conversation info (untrusted metadata): please ignore
|
||||||
|
\`\`\`json
|
||||||
|
{"x": 1}
|
||||||
|
\`\`\`
|
||||||
|
Real user content`;
|
||||||
|
expect(stripInboundMetadata(input)).toBe(input);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not strip sentinel text when json fence is missing", () => {
|
||||||
|
const input = `Sender (untrusted metadata):
|
||||||
|
name: test
|
||||||
|
Hello from user`;
|
||||||
|
expect(stripInboundMetadata(input)).toBe(input);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -32,8 +32,13 @@ const SENTINEL_FAST_RE = new RegExp(
|
|||||||
.join("|"),
|
.join("|"),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function isInboundMetaSentinelLine(line: string): boolean {
|
||||||
|
const trimmed = line.trim();
|
||||||
|
return INBOUND_META_SENTINELS.some((sentinel) => sentinel === trimmed);
|
||||||
|
}
|
||||||
|
|
||||||
function shouldStripTrailingUntrustedContext(lines: string[], index: number): boolean {
|
function shouldStripTrailingUntrustedContext(lines: string[], index: number): boolean {
|
||||||
if (!lines[index]?.startsWith(UNTRUSTED_CONTEXT_HEADER)) {
|
if (lines[index]?.trim() !== UNTRUSTED_CONTEXT_HEADER) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const probe = lines.slice(index + 1, Math.min(lines.length, index + 8)).join("\n");
|
const probe = lines.slice(index + 1, Math.min(lines.length, index + 8)).join("\n");
|
||||||
@@ -89,7 +94,12 @@ export function stripInboundMetadata(text: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Detect start of a metadata block.
|
// Detect start of a metadata block.
|
||||||
if (!inMetaBlock && INBOUND_META_SENTINELS.some((s) => line.startsWith(s))) {
|
if (!inMetaBlock && isInboundMetaSentinelLine(line)) {
|
||||||
|
const next = lines[i + 1];
|
||||||
|
if (next?.trim() !== "```json") {
|
||||||
|
result.push(line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
inMetaBlock = true;
|
inMetaBlock = true;
|
||||||
inFencedJson = false;
|
inFencedJson = false;
|
||||||
continue;
|
continue;
|
||||||
@@ -136,14 +146,14 @@ export function stripLeadingInboundMetadata(text: string): string {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!INBOUND_META_SENTINELS.some((s) => lines[index].startsWith(s))) {
|
if (!isInboundMetaSentinelLine(lines[index])) {
|
||||||
const strippedNoLeading = stripTrailingUntrustedContextSuffix(lines);
|
const strippedNoLeading = stripTrailingUntrustedContextSuffix(lines);
|
||||||
return strippedNoLeading.join("\n");
|
return strippedNoLeading.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
while (index < lines.length) {
|
while (index < lines.length) {
|
||||||
const line = lines[index];
|
const line = lines[index];
|
||||||
if (!INBOUND_META_SENTINELS.some((s) => line.startsWith(s))) {
|
if (!isInboundMetaSentinelLine(line)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user