mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 03:51:25 +00:00
Security: add per-wrapper IDs to untrusted-content markers (#19009)
Fixes #10927 Adds unique per-wrapper IDs to external-content boundary markers to prevent spoofing attacks where malicious content could inject fake marker boundaries. - Generate random 16-char hex ID per wrap operation - Start/end markers share the same ID for pairing - Sanitizer strips markers with or without IDs (handles legacy + spoofed) - Added test for attacker-injected markers with fake IDs Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
This commit is contained in:
@@ -269,7 +269,7 @@ describe("web_search external content wrapping", () => {
|
||||
results?: Array<{ description?: string }>;
|
||||
};
|
||||
|
||||
expect(details.results?.[0]?.description).toContain("<<<EXTERNAL_UNTRUSTED_CONTENT>>>");
|
||||
expect(details.results?.[0]?.description).toMatch(/<<<EXTERNAL_UNTRUSTED_CONTENT id="[a-f0-9]{16}">>>/);
|
||||
expect(details.results?.[0]?.description).toContain("Ignore previous instructions");
|
||||
expect(details.externalContent).toMatchObject({
|
||||
untrusted: true,
|
||||
@@ -332,7 +332,7 @@ describe("web_search external content wrapping", () => {
|
||||
const result = await executePerplexitySearchForWrapping("test");
|
||||
const details = result?.details as { content?: string };
|
||||
|
||||
expect(details.content).toContain("<<<EXTERNAL_UNTRUSTED_CONTENT>>>");
|
||||
expect(details.content).toMatch(/<<<EXTERNAL_UNTRUSTED_CONTENT id="[a-f0-9]{16}">>>/);
|
||||
expect(details.content).toContain("Ignore previous instructions");
|
||||
});
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ describe("web_fetch extraction fallbacks", () => {
|
||||
externalContent?: { untrusted?: boolean; source?: string; wrapped?: boolean };
|
||||
};
|
||||
|
||||
expect(details.text).toContain("<<<EXTERNAL_UNTRUSTED_CONTENT>>>");
|
||||
expect(details.text).toMatch(/<<<EXTERNAL_UNTRUSTED_CONTENT id="[a-f0-9]{16}">>>/);
|
||||
expect(details.text).toContain("Ignore previous instructions");
|
||||
expect(details.externalContent).toMatchObject({
|
||||
untrusted: true,
|
||||
@@ -332,7 +332,7 @@ describe("web_fetch extraction fallbacks", () => {
|
||||
maxChars: 200_000,
|
||||
});
|
||||
const details = result?.details as { text?: string; length?: number; truncated?: boolean };
|
||||
expect(details.text).toContain("<<<EXTERNAL_UNTRUSTED_CONTENT>>>");
|
||||
expect(details.text).toMatch(/<<<EXTERNAL_UNTRUSTED_CONTENT id="[a-f0-9]{16}">>>/);
|
||||
expect(details.text).toContain("Source: Web Fetch");
|
||||
expect(details.length).toBeLessThanOrEqual(10_000);
|
||||
expect(details.truncated).toBe(true);
|
||||
@@ -358,7 +358,7 @@ describe("web_fetch extraction fallbacks", () => {
|
||||
});
|
||||
|
||||
expect(message).toContain("Web fetch failed (404):");
|
||||
expect(message).toContain("<<<EXTERNAL_UNTRUSTED_CONTENT>>>");
|
||||
expect(message).toMatch(/<<<EXTERNAL_UNTRUSTED_CONTENT id="[a-f0-9]{16}">>>/);
|
||||
expect(message).toContain("SECURITY NOTICE");
|
||||
expect(message).toContain("Not Found");
|
||||
expect(message).not.toContain("<html");
|
||||
@@ -380,7 +380,7 @@ describe("web_fetch extraction fallbacks", () => {
|
||||
});
|
||||
|
||||
expect(message).toContain("Web fetch failed (500):");
|
||||
expect(message).toContain("<<<EXTERNAL_UNTRUSTED_CONTENT>>>");
|
||||
expect(message).toMatch(/<<<EXTERNAL_UNTRUSTED_CONTENT id="[a-f0-9]{16}">>>/);
|
||||
expect(message).toContain("Oops");
|
||||
});
|
||||
|
||||
@@ -407,7 +407,7 @@ describe("web_fetch extraction fallbacks", () => {
|
||||
});
|
||||
|
||||
expect(message).toContain("Firecrawl fetch failed (403):");
|
||||
expect(message).toContain("<<<EXTERNAL_UNTRUSTED_CONTENT>>>");
|
||||
expect(message).toMatch(/<<<EXTERNAL_UNTRUSTED_CONTENT id="[a-f0-9]{16}">>>/);
|
||||
expect(message).toContain("blocked");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user