diff --git a/.changeset/sixty-sloths-win.md b/.changeset/sixty-sloths-win.md new file mode 100644 index 000000000..5ac99700e --- /dev/null +++ b/.changeset/sixty-sloths-win.md @@ -0,0 +1,6 @@ +--- +"@saleor/handlebars": patch +"saleor-app-smtp": patch +--- + +Re-added `JSONparse` handlebars helper diff --git a/apps/smtp/src/modules/smtp/services/handlebars-template-compiler.test.ts b/apps/smtp/src/modules/smtp/services/handlebars-template-compiler.test.ts index 875baf8b1..854a19fa9 100644 --- a/apps/smtp/src/modules/smtp/services/handlebars-template-compiler.test.ts +++ b/apps/smtp/src/modules/smtp/services/handlebars-template-compiler.test.ts @@ -100,17 +100,14 @@ describe("HandlebarsTemplateCompiler", () => { expect(error.errorCode).toBe("HANDLEBARS_MISSING_HELPER"); }); - it("rejects object helpers: JSONparse (arbitrary object construction)", () => { + it("allows object helper: JSONparse", () => { const result = compiler.compile( - '{{JSONparse \'{"__proto__":{"admin":true}}\'}}', + '{{#with (JSONparse \'{"name":"test"}\')}}{{name}}{{/with}}', {}, ); - expect(result.isErr()).toBe(true); - - const error = result._unsafeUnwrapErr(); - - expect(error.errorCode).toBe("HANDLEBARS_MISSING_HELPER"); + expect(result.isOk()).toBe(true); + expect(result._unsafeUnwrap().template).toBe("test"); }); it("rejects object helpers: extend (prototype pollution)", () => { diff --git a/packages/handlebars/src/allowed-helpers.ts b/packages/handlebars/src/allowed-helpers.ts index 920710e09..302fd5ae6 100644 --- a/packages/handlebars/src/allowed-helpers.ts +++ b/packages/handlebars/src/allowed-helpers.ts @@ -131,7 +131,8 @@ export const ALLOWED_HELPERS: Record = { "toPrecision", ], - // --- object: removed entirely --- + // --- object (extend, merge removed – prototype pollution risk) --- + object: ["JSONparse"], // --- path (resolve removed) --- path: ["absolute", "dirname", "relative", "basename", "stem", "extname", "segments"], diff --git a/packages/handlebars/src/register-allowed-helpers.test.ts b/packages/handlebars/src/register-allowed-helpers.test.ts index 3dbf2120f..546db4d96 100644 --- a/packages/handlebars/src/register-allowed-helpers.test.ts +++ b/packages/handlebars/src/register-allowed-helpers.test.ts @@ -46,7 +46,7 @@ describe("registerAllowedHelpers", () => { }); describe("removed groups are not loaded", () => { - it.each(["fs", "logging", "markdown", "match", "object"])( + it.each(["fs", "logging", "markdown", "match"])( "does not include removed group: %s", (group) => { expect( @@ -57,6 +57,17 @@ describe("registerAllowedHelpers", () => { ); }); + describe("dangerous object helpers are not registered", () => { + it.each(["extend", "merge"])( + "does not register dangerous object helper: %s", + (name) => { + registerAllowedHelpers(hbs, handlebarsHelpers); + + expect(hbs.helpers[name], `Helper "${name}" should NOT be registered`).toBeUndefined(); + }, + ); + }); + describe("individually removed helpers are not registered", () => { it.each(["embed", "resolve"])( "does not register removed helper: %s",