-
Notifications
You must be signed in to change notification settings - Fork 1
Security
You can learn the security risks of the browsers, security issues when storing the user's private keys and the measures Skia Wallet team is taking into account.
Our ønly security measures we're taking is using security tools to find and fix security vulnerabilities in code and dependencies:
- Snyk.io
- Github's security bot Dependabot to find automatically new security issues after each new update of the code.
We need to improve multiple facets of all kind of attacks described below.
Here you've a list of common attacks:
- Hacks in multi-factor authentication solutions by Roger Grimes in RSA Conference 2019
- Problems with passwords by Alex Winert in Microsoft Security
- Cross-Site Scripting or XSS link 1, link 2
- Cross-Site Request Forgery or CSRF
- More attacks on OWASP list, cheat sheets
Here you'll discover how Skia Wallet saves the mnemonic key of the persons on the browsers. The company Auth0 is recognized for offering to the software developers an easy way to implement, adaptable authentication and authorization for their apps and websites.
They wrote an article "Secure Browser Storage: The Facts" in 2021 storing data and attacking the code with the common security issues (). The next popular storage techniques were attacked:
- Local Storage or
localStorage
. Read about its technical details on MDN. - Session Storage or
sessionStorage
. Read about it on MDN. - Cookies. Read about it on MDN
- In memory. It stores the data temporary, this means if you refresh the page, it'll go away.
A long list by [OWASP][owasp-cheatsheets] of the most common attacks and how to prevent them.
Skia Wallet team has to work on the next areas:
- [To do] Cross-Site Scripting or XSS.
- [To do] Cross-Site Request Forgery or CSRF
- [To do] Sanitize the inputs with the Javascript library DOMPurify (its goals here). It's a common issue on multiple type of attacks.
- [To do] Set up the HTML headers:
X-Frame-Options
,X-XSS-Protection
,X-Content-Type-Options
,Referrer-Policy
,Content-Type
,Strict-Transport-Security
,Content-Security-Policy
,Access-Control-Allow-Origin
,Cross-Origin-Opener-Policy
,Cross-Origin-Resource-Policy
,Cross-Origin-Embedder-Policy
, removeX-Powered-By
. - [To do] Require multi-factor authentication for admins. In places like the codebase (2FA on Github, GPG on Github)
Secondary:
- Good practices for software developers according to:
- Google: security for websites
- Microsoft: Security Development Lifecycle, mitigate supply chain attacks
- CSS
- Javascript package manager NPM
- NodeJS
MetaMask is the most famous software cryptocurrency wallet used to interact with the Ethereum blockchain. It allows users to access their Ethereum wallet through a browser extension or mobile app, which can then be used to interact with decentralized applications. MetaMask is developed by ConsenSys Software Inc., a blockchain software company focusing on Ethereum-based tools and infrastructure.
Then it's a good source to understand how they save the user's data.
First, let's check the its code architecture here
ℹ️ Some of the links below point to lines of code at one moment in time. If you want to read the latest code, switch to the related project's default branch (e.g.
main
,develop
...)
Metamask extension uses LavaMoat to package all the code (here is the line in a secure way to prevent software supply chain attacks. Microsoft explains here that "software vendors are likely unaware that their apps or updates are infected with malicious code when they're released to the public. The malicious code then runs with the same trust and permissions as the app. The number of potential victims is significant, given the popularity of some apps. A case occurred where a free file compression app was poisoned and deployed to customers in a country where it was the top utility app."
LavaMoat's creator did a talk in Speakeasy JS in 2021 about an attack dono to a Javacript library used by multiple projects in the blockchain.
List of ways Metamask saves the user's data:
- Explanation of the Metamask model of account security.
- Browser extensions needs to write a manifest file to tell to the browsers the permissions, icons... they gonna use. Metamask's manifest has a permission for storage (here is the documentation from Chrome team and from MDN, it's very similar as
localStorage
but with some differences commented in the previous link. At some point (2018), it switched fromlocalStorage
tochrome.storage.local
(reference 1,), reference 2), find therYou can open the Developer Tools for the Metamask Extension of the browser where it's installed, then on the console, run the next command (read more clicking the previous documentation link):
chrome.storage.local.get('data', result => {
var vault = result.data.KeyringController.vault
console.log(vault)
})
- The file
local-store.js
is where Metamask connect to the browser's extension storage. It usesbrowser.storage.local
to do so and it is provided by the Javascript library webextension-polyfill. - The file
background.js
contains big part of the data management of the Metamask extension.-
initApp
is where big part ofbackground
code is initialized. -
persistData
is runned during the initializationinitApp
in the line #167. Here, it uses the filelocal-store.js
.
-
-
MetamaskController
: used to store the user's state related to the Metamask extension. Where is it called? in file background - User's preferences (locale, features that user wants to see...) are saved in the field called
store
inPreferencesController
. - A common Javascript library used by Metamask is @metamask/obs-store, also called
ObservableStore
or vault. The main code is here. - For creating, deleting... the private keys, the Javascript library used is Keyring Controller. The library uses the library
ObservableStore
to store data. The code is here. Some of its methods:-
createNewVaultAndRestore
). It "destroys any old encrypted storage, creates a new encrypted store with the given password, creates a new HD wallet from the given seed with 1 account." -
persistAllKeyrings
is runned insidecreateNewVaultAndRestore
. It encrypts (with browser-passworder and stores (withObservableStore
) the user's mnemonic key (also called seed phrase). Inside it, the encryption of the mnemonic happens using the password. On every browser and mobile app where Metamask is installed, it encrypts the data with the password that the user decides for each one. This is explained in the documentation.
-
- Metamask, as said previously, stores the mnemonic key encrypted. MDN says "the storage area is not encrypted and shouldn't be used for storing confidential user information." On the Metamask's forum, they talk about where the file with the keys is saved. To decrypt it, you'll need the password and the use the correct protocol.
There's another technology that browsers supports called Web Workers that guarantee that the data remains inside a Web Worker and cannot be accessed from outside, like an attacker.
"Web workers enable developers to benefit from parallel programming in JavaScript. Parallel programming allows applications to run different computations at the same time." according to Auth0. "Web Workers are a simple means for web content to run scripts in background threads. The worker thread can perform tasks without interfering with the user interface." by MDN
Image from [Auth0]
"The Worker interface spawns real OS-level threads, and mindful programmers may be concerned that concurrency can cause effects in your code if you aren't careful. However, since web workers have carefully controlled communication points with other threads, it's actually very hard to cause concurrency problems. There's no access to non-threadsafe components or the DOM. And you have to pass specific data in and out of a thread through serialized objects. So you have to work really hard to cause problems in your code. by MDN
"Web Workers can run JavaScript code in a background thread separate from the main execution thread of the JS frontend application. They communicate with the frontend application via a channel called MessageChannel. Specifically, the application can send a message to the Web Worker to perform some action via the MessageChannel. The Web Worker will perform the action and send back to the application the needed information." by Auth0. "With Web Workers, the secret is available in the isolated JavaScript code of the Web Worker. If JS frontend code needs access to the secret, the Web Worker implementation is the only one satisfying the requirement while preserving the secret confidentiality.".
Bruce Wilson says "any data that is passed via postMessage()
" (the method used by Web Worker to communicate with the main thread) "is copied before it is passed, so changing the data in the main window thread does not result in changes to the data in the worker thread. This provides inherent protection from conflicting concurrent changes to data that’s passed between main thread and worker thread".
Benefits of Web Workers over the previous storing web techniques:
- The other techniques to store data explained above (
localStorage
,sessionStorage
and cookies) are more vulnerable to attacks. - Supported by all major mobile and desktop browsers. Can I Use shows the compatibility table and supported by ~96% of browser's user in the world.
- It prevents third-party code from accessing mnemonic key and HTTP-request interceptions. Since third-party codes run on the main thread, they cannot intercept requests initiated by the web workers. Yes, when we store access tokens in web workers, API requests needing those access tokens should also be initiated from the web workers.
Some concerns found on the documentation and Internet:
- MDN "Workers are considered to have their own execution context, distinct from the document that created them. For this reason they are, in general, not governed by the content security policy of the document (or parent worker) that created them. [...] To specify a content security policy for the worker, set a Content-Security-Policy response header for the request which delivered the worker script itself."
-
HTML5 Security Cheat Sheet by OWASP
- Web Workers are allowed to use XMLHttpRequest object to perform in-domain and Cross Origin Resource Sharing requests. See relevant section of this Cheat Sheet to ensure CORS security.
- While Web Workers don't have access to DOM of the calling page, malicious Web Workers can use excessive CPU for computation, leading to Denial of Service condition or abuse Cross Origin Resource Sharing for further exploitation. Ensure code in all Web Workers scripts is not malevolent. Don't allow creating Web Worker scripts from user supplied input.
- Validate messages exchanged with a Web Worker. Do not try to exchange snippets of JavaScript for evaluation e.g. via eval() as that could introduce a DOM Based XSS vulnerability.
- Questions about security risks on Stack Overflow
- Answer: "the MessagePort interface is 100% client-side. A compromised machine could have a malicious script read directly in its RAM and derive the sensitive information from there, but once again, if they can do it... they can certainly access that token by means a lot simpler.".
-
Mozilla Security Review in 2008:
- Workers execute in a tightly controlled sandbox.
- No access to Components or other global JS components.
- Only basic JS (Math, Date, etc.), timeouts, XHR, and importScripts.
- No pref dependencies yet, maybe will provide one to customize the number of OS threads allowed.
- Script loading is subject to the same restrictions as on the main thread (content policies, same origin restrictions, etc.).
- XHR uses the same code as the main thread.