fix(security): classify hook sessions case-insensitively

This commit is contained in:
Brian Mendonca
2026-02-24 12:33:35 -07:00
committed by Peter Steinberger
parent 43a3ff3beb
commit 9924f7c84e
2 changed files with 20 additions and 6 deletions

View File

@@ -246,6 +246,12 @@ describe("external-content security", () => {
expect(isExternalHookSession("hook:custom:456")).toBe(true);
});
it("identifies mixed-case hook prefixes", () => {
expect(isExternalHookSession("HOOK:gmail:msg-123")).toBe(true);
expect(isExternalHookSession("Hook:custom:456")).toBe(true);
expect(isExternalHookSession(" HOOK:webhook:123 ")).toBe(true);
});
it("rejects non-hook sessions", () => {
expect(isExternalHookSession("cron:daily-task")).toBe(false);
expect(isExternalHookSession("agent:main")).toBe(false);
@@ -266,6 +272,12 @@ describe("external-content security", () => {
expect(getHookType("hook:custom:456")).toBe("webhook");
});
it("returns hook type for mixed-case hook prefixes", () => {
expect(getHookType("HOOK:gmail:msg-123")).toBe("email");
expect(getHookType(" HOOK:webhook:123 ")).toBe("webhook");
expect(getHookType("Hook:custom:456")).toBe("webhook");
});
it("returns unknown for non-hook sessions", () => {
expect(getHookType("cron:daily")).toBe("unknown");
});

View File

@@ -286,10 +286,11 @@ export function buildSafeExternalPrompt(params: {
* Checks if a session key indicates an external hook source.
*/
export function isExternalHookSession(sessionKey: string): boolean {
const normalized = sessionKey.trim().toLowerCase();
return (
sessionKey.startsWith("hook:gmail:") ||
sessionKey.startsWith("hook:webhook:") ||
sessionKey.startsWith("hook:") // Generic hook prefix
normalized.startsWith("hook:gmail:") ||
normalized.startsWith("hook:webhook:") ||
normalized.startsWith("hook:") // Generic hook prefix
);
}
@@ -297,13 +298,14 @@ export function isExternalHookSession(sessionKey: string): boolean {
* Extracts the hook type from a session key.
*/
export function getHookType(sessionKey: string): ExternalContentSource {
if (sessionKey.startsWith("hook:gmail:")) {
const normalized = sessionKey.trim().toLowerCase();
if (normalized.startsWith("hook:gmail:")) {
return "email";
}
if (sessionKey.startsWith("hook:webhook:")) {
if (normalized.startsWith("hook:webhook:")) {
return "webhook";
}
if (sessionKey.startsWith("hook:")) {
if (normalized.startsWith("hook:")) {
return "webhook";
}
return "unknown";