mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 07:27:40 +00:00
security(hooks): block prototype-chain traversal in webhook template getByPath (#22213)
* security(hooks): block prototype-chain traversal in webhook template getByPath The getByPath() function in hooks-mapping.ts traverses attacker-controlled webhook payload data using arbitrary property path expressions, but does not filter dangerous property names (__proto__, constructor, prototype). The config-paths module (config-paths.ts) already blocks these exact keys for config path traversal via a BLOCKED_KEYS set, but the hooks template system was not protected with the same guard. Add a BLOCKED_PATH_KEYS set mirroring config-paths.ts and reject traversal into __proto__, prototype, or constructor in getByPath(). Add three test cases covering all three blocked keys. Signed-off-by: Alan Ross <alan@sleuthco.ai> * test(gateway): narrow hook action type in prototype-pollution tests * changelog: credit hooks prototype-path guard in PR 22213 * changelog: move hooks prototype-path fix into security section --------- Signed-off-by: Alan Ross <alan@sleuthco.ai> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
This commit is contained in:
@@ -438,6 +438,11 @@ function resolveTemplateExpr(expr: string, ctx: HookMappingContext) {
|
||||
return getByPath(ctx.payload, expr);
|
||||
}
|
||||
|
||||
// Block traversal into prototype-chain properties on attacker-controlled
|
||||
// webhook payloads. Mirrors the same blocklist used by config-paths.ts
|
||||
// for config path traversal.
|
||||
const BLOCKED_PATH_KEYS = new Set(["__proto__", "prototype", "constructor"]);
|
||||
|
||||
function getByPath(input: Record<string, unknown>, pathExpr: string): unknown {
|
||||
if (!pathExpr) {
|
||||
return undefined;
|
||||
@@ -465,6 +470,9 @@ function getByPath(input: Record<string, unknown>, pathExpr: string): unknown {
|
||||
current = current[part] as unknown;
|
||||
continue;
|
||||
}
|
||||
if (BLOCKED_PATH_KEYS.has(part)) {
|
||||
return undefined;
|
||||
}
|
||||
if (typeof current !== "object") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user