diff --git a/packages/snaps-controllers/src/snaps/SnapController.ts b/packages/snaps-controllers/src/snaps/SnapController.ts index c547231b21..3d365eaca7 100644 --- a/packages/snaps-controllers/src/snaps/SnapController.ts +++ b/packages/snaps-controllers/src/snaps/SnapController.ts @@ -3943,17 +3943,26 @@ export class SnapController extends BaseController< const { conversions: requestedConversions } = requestedParams; const filteredConversionRates = requestedConversions.reduce< - Record> + Map> >((accumulator, conversion) => { const rate = conversionRates[conversion.from]?.[conversion.to]; // Only include rates that were actually requested. if (rate) { - accumulator[conversion.from] ??= {}; - accumulator[conversion.from][conversion.to] = rate; + if (!accumulator.has(conversion.from)) { + accumulator.set(conversion.from, new Map()); + } + accumulator.get(conversion.from).set(conversion.to, rate); } return accumulator; - }, {}); - return { conversionRates: filteredConversionRates }; + }, new Map()); + // Convert nested Maps into plain objects for return value compatibility. + const conversionRatesObj = Object.fromEntries( + Array.from(filteredConversionRates.entries()).map(([fromKey, toMap]) => [ + fromKey, + Object.fromEntries(toMap.entries()), + ]), + ); + return { conversionRates: conversionRatesObj }; } /** @@ -3980,11 +3989,13 @@ export class SnapController extends BaseController< const result = marketData[assets.asset]?.[assets.unit]; // Only include rates that were actually requested. if (result) { - accumulator[assets.asset] ??= {}; + if (!accumulator[assets.asset]) { + accumulator[assets.asset] = Object.create(null); + } accumulator[assets.asset][assets.unit] = result; } return accumulator; - }, {}); + }, Object.create(null)); return { marketData: filteredMarketData }; } diff --git a/packages/snaps-rpc-methods/src/permitted/setState.ts b/packages/snaps-rpc-methods/src/permitted/setState.ts index b03e2c11d8..0b6e1ad5e5 100644 --- a/packages/snaps-rpc-methods/src/permitted/setState.ts +++ b/packages/snaps-rpc-methods/src/permitted/setState.ts @@ -260,9 +260,15 @@ export function set( for (let i = 0; i < keys.length; i++) { const currentKey = keys[i]; - if (FORBIDDEN_KEYS.includes(currentKey)) { + // Explicitly block prototype pollution keys + if ( + FORBIDDEN_KEYS.includes(currentKey) || + currentKey === '__proto__' || + currentKey === 'constructor' || + currentKey === 'prototype' + ) { throw rpcErrors.invalidParams( - 'Invalid params: Key contains forbidden characters.', + 'Invalid params: Key contains forbidden characters or is potentially prototype polluting.', ); }