mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 23:28:27 +00:00
fix(security): separate untrusted channel metadata from system prompt (thanks @KonstantinMirin)
This commit is contained in:
45
src/security/channel-metadata.ts
Normal file
45
src/security/channel-metadata.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { wrapExternalContent } from "./external-content.js";
|
||||
|
||||
const DEFAULT_MAX_CHARS = 800;
|
||||
const DEFAULT_MAX_ENTRY_CHARS = 400;
|
||||
|
||||
function normalizeEntry(entry: string): string {
|
||||
return entry.replace(/\s+/g, " ").trim();
|
||||
}
|
||||
|
||||
function truncateText(value: string, maxChars: number): string {
|
||||
if (maxChars <= 0) {
|
||||
return "";
|
||||
}
|
||||
if (value.length <= maxChars) {
|
||||
return value;
|
||||
}
|
||||
const trimmed = value.slice(0, Math.max(0, maxChars - 3)).trimEnd();
|
||||
return `${trimmed}...`;
|
||||
}
|
||||
|
||||
export function buildUntrustedChannelMetadata(params: {
|
||||
source: string;
|
||||
label: string;
|
||||
entries: Array<string | null | undefined>;
|
||||
maxChars?: number;
|
||||
}): string | undefined {
|
||||
const cleaned = params.entries
|
||||
.map((entry) => (typeof entry === "string" ? normalizeEntry(entry) : ""))
|
||||
.filter((entry) => Boolean(entry))
|
||||
.map((entry) => truncateText(entry, DEFAULT_MAX_ENTRY_CHARS));
|
||||
const deduped = cleaned.filter((entry, index, list) => list.indexOf(entry) === index);
|
||||
if (deduped.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const body = deduped.join("\n");
|
||||
const header = `UNTRUSTED channel metadata (${params.source})`;
|
||||
const labeled = `${params.label}:\n${body}`;
|
||||
const truncated = truncateText(`${header}\n${labeled}`, params.maxChars ?? DEFAULT_MAX_CHARS);
|
||||
|
||||
return wrapExternalContent(truncated, {
|
||||
source: "channel_metadata",
|
||||
includeWarning: false,
|
||||
});
|
||||
}
|
||||
@@ -67,6 +67,7 @@ export type ExternalContentSource =
|
||||
| "email"
|
||||
| "webhook"
|
||||
| "api"
|
||||
| "channel_metadata"
|
||||
| "web_search"
|
||||
| "web_fetch"
|
||||
| "unknown";
|
||||
@@ -75,6 +76,7 @@ const EXTERNAL_SOURCE_LABELS: Record<ExternalContentSource, string> = {
|
||||
email: "Email",
|
||||
webhook: "Webhook",
|
||||
api: "API",
|
||||
channel_metadata: "Channel metadata",
|
||||
web_search: "Web Search",
|
||||
web_fetch: "Web Fetch",
|
||||
unknown: "External",
|
||||
|
||||
Reference in New Issue
Block a user