MetaMask Security April Team Report

Ensuring MetaMask is safe, secure, and stable enough for continued viral growth.

by LukerMay 5, 2022
No news image available

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.

Flame graph at the beginning of the second iteration
Flame graph at the beginning of the second iteration.
Flame graph after all optimizations
Flame graph after all optimizations. The hottest function is running JSON.parse on data we need.

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:

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

Security Team

Hiring

We are looking for 4 engineer positions:

Receive our Newsletter