Skip to content

Conversation

odaysec
Copy link

@odaysec odaysec commented Sep 18, 2025

Summary

Fix: Replace unsafe object keys with validations or safe structures (Map / Object.create(null))

This pull request addresses multiple prototype pollution vulnerabilities across different controllers in the MetaMask/core. The root cause in all cases was the usage of untrusted dynamic keys (chainId, namespace, etc.) on plain JavaScript objects, which could allow pollution via special keys like __proto__, constructor, or prototype.

Changes Implemented

1. AccountTrackerController.ts (updateNativeBalances, updateStakedBalances)

  • Added guard checks inside iteration loops to skip dangerous keys:

    • "__proto__"
    • "constructor"
    • "prototype"
  • Prevents updates to polluted object prototypes.

2. TokenBalancesController.ts

  • Inserted validation before assigning chainId keys in loops around lines 596–632.
  • Dangerous keys are now skipped with an explicit continue.

3. earn-controller/selectors.ts

  • Replaced nested plain objects with Map for storing protocol → id → LendingMarket mappings.
  • Updated selectors (selectLendingMarketsByProtocolAndId, selectLendingMarketForProtocolAndId) to use .get() instead of unsafe property access.
  • Updated return types to reflect Map usage.

4. EnsController.ts (delete method)

  • Added explicit guard before performing delete state.ensEntries[chainId][normalizedEnsName].
  • Ensures polluted keys (__proto__, etc.) are never used for deletion operations.

5. NameController.ts (#updateEntry)

  • Replaced {} object instantiations with Object.create(null) for:

    • state.names
    • typeEntries
    • variationEntries
  • Ensures prototype-less storage to prevent pollution.

6. NetworkEnablementController.ts (enableNetworkInNamespace)

  • Added validation step after namespace checks.
  • If namespace matches a forbidden key (__proto__, constructor, prototype), an Error is thrown and the update is rejected.

7. sample-petnames-controller.ts (assignPetname)

  • Extended validation to explicitly reject dangerous property names.
  • Throws error if chainId equals __proto__, constructor, or prototype.

Notes

  • All changes are backwards-compatible with current controller APIs.
  • Where full refactoring to Map was infeasible, localized guards were added for defense-in-depth.
  • Object.prototype.proto
  • Map

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed, highlighting breaking changes as necessary
  • I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes

@odaysec odaysec requested review from a team as code owners September 18, 2025 21:21
Copy link

@poratoes poratoes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR provides a comprehensive and robust fix for prototype pollution vulnerabilities by validating and safeguarding dynamic keys across multiple controllers. The use of secure data structures and explicit guards improves security while maintaining backward compatibility. All changes are well-documented and tested. I approve these changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants