mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-26 05:13:33 +00:00
fix(security): harden hook session-key normalization (#25750) (thanks @bmendonca3)
This commit is contained in:
@@ -252,6 +252,11 @@ describe("external-content security", () => {
|
||||
expect(isExternalHookSession(" HOOK:webhook:123 ")).toBe(true);
|
||||
});
|
||||
|
||||
it("identifies Unicode full-width hook prefixes", () => {
|
||||
expect(isExternalHookSession("HOOK:gmail:msg-123")).toBe(true);
|
||||
expect(isExternalHookSession("HOOK:custom:456")).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects non-hook sessions", () => {
|
||||
expect(isExternalHookSession("cron:daily-task")).toBe(false);
|
||||
expect(isExternalHookSession("agent:main")).toBe(false);
|
||||
@@ -278,6 +283,11 @@ describe("external-content security", () => {
|
||||
expect(getHookType("Hook:custom:456")).toBe("webhook");
|
||||
});
|
||||
|
||||
it("returns hook type for Unicode full-width hook prefixes", () => {
|
||||
expect(getHookType("HOOK:gmail:msg-123")).toBe("email");
|
||||
expect(getHookType(" HOOK:custom:456 ")).toBe("webhook");
|
||||
});
|
||||
|
||||
it("returns unknown for non-hook sessions", () => {
|
||||
expect(getHookType("cron:daily")).toBe("unknown");
|
||||
});
|
||||
|
||||
@@ -285,8 +285,14 @@ export function buildSafeExternalPrompt(params: {
|
||||
/**
|
||||
* Checks if a session key indicates an external hook source.
|
||||
*/
|
||||
function normalizeHookSessionKey(sessionKey: string): string {
|
||||
// NFKC folds common full-width forms so hook-prefix checks cannot be bypassed by
|
||||
// visually similar Unicode spellings like "HOOK:...".
|
||||
return sessionKey.normalize("NFKC").trim().toLowerCase();
|
||||
}
|
||||
|
||||
export function isExternalHookSession(sessionKey: string): boolean {
|
||||
const normalized = sessionKey.trim().toLowerCase();
|
||||
const normalized = normalizeHookSessionKey(sessionKey);
|
||||
return (
|
||||
normalized.startsWith("hook:gmail:") ||
|
||||
normalized.startsWith("hook:webhook:") ||
|
||||
@@ -298,7 +304,7 @@ export function isExternalHookSession(sessionKey: string): boolean {
|
||||
* Extracts the hook type from a session key.
|
||||
*/
|
||||
export function getHookType(sessionKey: string): ExternalContentSource {
|
||||
const normalized = sessionKey.trim().toLowerCase();
|
||||
const normalized = normalizeHookSessionKey(sessionKey);
|
||||
if (normalized.startsWith("hook:gmail:")) {
|
||||
return "email";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user