Enhancing Local Storage Security in Chrome Extensions
- Storages In Browser
- Same-Origin Policy
- Malicious Extension
In modern web development, there are several storage options available in browsers
base on browser implementation
LocalStorage
- Persistence: Data persists even after the browser is closed and reopened.
- Capacity: Typically around 5MB.
- Accessibility: Same-origin policy applies (only accessible by pages from the same domain).
- Use Case: Storing user preferences or saving state across sessions.
SessionStorage
- Persistence: Data is cleared when the page session ends (i.e., when the tab or browser is closed).
- Capacity: Similar to LocalStorage, around 5MB.
- Accessibility: Same-origin policy applies, and data is only available in the window/tab where it was set.
- Use Case: Storing data needed for the current session, like form data in a multi-step process.
Cookies
- Persistence: Configurable expiration date; can persist across browser sessions.
- Capacity: Very limited (about 4KB).
- Accessibility: Can be configured to be accessible by multiple pages or across subdomains.
- Use Case: Tracking sessions, storing small pieces of user data, and can be used for server-side read/write.
accessToken/sessionToken
In Server, it is a common pratice to protect sensetive data
ctx.setCookie('token', token, {
httpOnly: true,
secure: true,
path: '/',
sameSite: envs.NODE_ENV === 'production' ? true : 'none',
});
HTTP Response Header
IndexedDB
- Persistence: Persistent storage, survives browser restarts.
- Capacity: Significantly larger than LocalStorage (no fixed limit, but browser may prompt the user for permission if the limit is exceeded).
- Accessibility: Same-origin policy applies.
- Use Case: Storing large amounts of structured data, offline storage, and for applications that require more complex database-like capabilities.
Wrap up
localStorage/sessionStorage
cookies
non sensitive data (user config)
sensitive data (token)
WHAT IF......
Same Origin Policy
There's still a line of defense left
Source URL | Compared URL | Same Origin? | Reason |
---|---|---|---|
http://example.com | http://subdomain.example.com | No | Different subdomains |
https://example.com | http://example.com | No | Different protocols (https vs http) |
http://example.com:80 | http://example.com:8080 | No | Different ports (80 vs 8080) |
http://subdomain.example.com | http://another.example.com | No | Different subdomains |
http://example.com/abc | http://example.com/bcd | Yes | Same protocol, subdomain, and port |
Malicious Extension
Web extensions
content script
background script
execute in individual tabs
execute in background
Chrome API is powerful!
// content script
const allLocalStorage = {};
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
allLocalStorage[key] = localStorage.getItem(key);
}
const domain = new URL(window.location.href).hostname;
chrome.storage.local.set({ [domain]: allLocalStorage }, function() {
console.log(`LocalStorage for ${domain} is saved to chrome.storage.local`);
});
Access your localStorage and save it somewhere for easy retrieval and future use
Even we can hijack web API
((win) => {
const nativeLocalStorage = win.localStorage;
win.nativeLocalStorage = nativeLocalStorage; // keep the original usage
class MyLocalStorage extends Storage {
setItem(key, value) {
const secret = encrypt(value, passphrase);
nativeLocalStorage.setItem(key, secret);
}
getItem(key) {
const secret = nativeLocalStorage.getItem(key);
return secret ? decrypt(secret, passphrase) : null;
}
}
const myLocalStorage = new MyLocalStorage();
// Assign the newly created instance to localStorage
Object.defineProperty(win, 'localStorage', {
value: myLocalStorage,
writable: true,
});
win.localStorage = myLocalStorage;
console.log("window.localStorage", win.localStorage)
})(window);
- Encryption Sensitive Data
- Extension Management
Avoidance Strategy
localStorage
Web API
developer console
File(leveldb)
Access Methods
localStorage
Web API
developer console
File(leveldb)
Access Methods
encryption data
encryption data
getItem method
Extension Management
{
"name": "Permissions Extension",
...
"permissions": [
"activeTab",
"contextMenus",
"storage"
],
"optional_permissions": [
"topSites",
],
"host_permissions": [
"https://www.developer.chrome.com/*"
],
"optional_host_permissions":[
"https://*/*",
"http://*/*"
],
...
"manifest_version": 3
}
Research on Enhancing Local Storage Security in Chrome Extensions
By Jay Chou
Research on Enhancing Local Storage Security in Chrome Extensions
- 65