MetaMask Security April Team Report
Ensuring MetaMask is safe, secure, and stable enough for continued viral growth.
Research
Endo
Endo CommonJS support
CommonJS progress tracking epic: https://github.com/endojs/endo/issues/1055
End-to-end tests on real packages from npm ecosystem — mostly selected from MetaMask dependencies — have surfaced many cases where support for CommonJS was insufficient and helped drive the implementation.
A test comparing multiple shapes of exports from CommonJS imported in ESM across Endo, Node.js and a selection of bundlers helped set goals and avoid regressions. https://github.com/endojs/endo-e2e-tests/blob/main/matrix/table.md
Most notable changes in Endo CommonJS support:
- Wired up exports to import * and introduced implicit default export,
- Improved lexer to detect all occurrences of require and postponed missing package errors to runtime so that they don’t get thrown if a require call is actually a call to local function called require which does not load packages,
- Refactored exports handling to make module.exports the default and identify named exports.
- Support for nested package.json with type:module and arrays of optional values in package.json->exports
Endo now supports loading CommonJS modules correctly. All new issues when loading real packages from npm boil down to:
- use of missing features (like require.resolve or import.meta)
- messing with globals/intrinsics
- triggering filters protecting form injecting imports or HTML comments
- incorrect export mapping and module type resolution by Endo.
Endo command to run code
Based on existing tooling used to wire up endo e2e tests it was possible to create an experimental implementation of an endo run command which can execute a JS file just like node app.js but with compartments https://github.com/endojs/endo/pull/1168
Currently all node core modules are made available to require/import by the codebase and dependencies. Further work should add support for policies from LavaMoat.
LavaMoat
LavaMoat ‘a’a package naming
LavaMoat v6 shipped with a new package identifier notation to prevent issues from impersonation and/or package name reuse. The notation itself has been dubbed ‘a’a and is now being used for keys in policy files.
The initial implementation performance was heavily impacted by inefficiencies in Node.js when looking up and accessing files. Initial attempt at performance improvement was limited to 2 cases of simple memoization. It took the worst-case execution time of ‘a’a in metamask-extension from 10 minutes to 30 seconds. The cost of spikes in memory usage was too high though.
Second iteration of performance diagnostics and improvements in ‘a’a https://github.com/LavaMoat/LavaMoat/pull/332
- over 25x less time and RAM compared to the first iteration results
- new algorithm
- eliminated recursion
- local performance improvements to node-resolve
In total, the execution time improvement was roughly 600x between the first complete implementation and current.
LavaMoat v6 rollout to extension
https://github.com/MetaMask/metamask-extension/pull/14488
MetaMask Extension is running under protections of the new LavaMoat.
React Native compatibility
The fundamental key to make LavaMoat operative to React Native applications is to be able to run the lockdown function.
The SES lockdown() function is a key artifact to protect your software against supply chain attacks. By listing the primordials in JavaScript and freezing prototypes, lockdown() makes it unlikely for a malicious actor to perform a prototype pollution attack.
A detailed writeup of the insights found during this engagement is in this issue. From a birds’ eye view, the key facts to accomplish compatibility are:
- Allow metro to run the SES bundle by running .cjs files
- Add specific lockdown options
- Removing babel plugins
- Remove the promise polyfill
There are other issues but are specific to the MetaMask mobile application such as Sentry and EthereumJS dependencies.
The result is a Pull Request into the MetaMask mobile application repository. Next steps include to run End-to-End tests to make sure that lockdown didn’t break any more functionality and we can jump into the next stage which is running LavaMoat into MetaMask Mobile.
Threat Intelligence
iCloud backup
- If you have enabled iCloud backup for app data, this will include your password-encrypted MetaMask vault. Follow this link to get steps to control this feature on your device:
- https://twitter.com/MetaMask/status/1515727239391809536
Security Team
Hiring
Keep reading our latest stories
Developers, security news, and more