Sync cookies across browsers using GitHub Gist with E2E encryption (AES-GCM + PBKDF2-SHA256)
A secure cookie synchronization tool that uses GitHub Gist as storage with end-to-end AES-GCM encryption.
Author: hxueh
Version: 0.0.4
License: MIT
This script uses per-domain synchronization with a metadata index:
your-gist/
├── cookie-sync-metadata.json (encrypted) - index of all synced domains
├── cookies_github.com.json (encrypted) - github.com cookies
├── cookies_google.com.json (encrypted) - google.com cookies
└── ...
syncKeys selection (cookie names)syncKeys is empty → push all cookies for the domainsyncKeys has values → push only those cookiessyncKeys and cookies in the remote filesyncKeys from remote filesyncKeys is empty → apply all cookies in filesyncKeys has values → apply only those cookiessyncKeys selection to match remote[] = all cookies are syncedInstall the Tampermonkey extension for your browser:
Cookie Synccookie-sync.user.jsgithub.com)github.com)Browser A (source):
1. Go to github.com
2. Select sync keys: ["logged_in", "user_session"]
3. Push → uploads those 2 cookies + syncKeys: ["logged_in", "user_session"]
Browser B (destination):
1. Go to github.com
2. Pull → reads syncKeys from remote, applies only logged_in and user_session
3. Local syncKeys selection now shows: ["logged_in", "user_session"]
Browser A:
1. Select no keys (leave all unchecked)
2. Push → uploads all cookies + syncKeys: []
Browser B:
1. Pull → syncKeys is empty, so all cookies are applied
┌─────────────────────────────────────────────────────────────┐
│ Cookie Data (JSON) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ PBKDF2-SHA256 Key Derivation │
│ - Password + Random Salt (16 bytes) │
│ - 100,000 iterations │
│ - Produces 256-bit AES key │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ AES-256-GCM Encryption │
│ - Random IV (12 bytes) │
│ - Authenticated encryption │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Base64 Encoded Output: [Salt][IV][Ciphertext+AuthTag] │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ GitHub Gist (Private) │
└─────────────────────────────────────────────────────────────┘
cookie-sync-metadata.json){
"domains": ["github.com", "google.com"],
"lastUpdated": 1737312000000
}
cookies_github.com.json){
"timestamp": 1737312000000,
"domain": "github.com",
"syncKeys": ["logged_in", "user_session"],
"cookies": {
"logged_in": {
"value": "yes",
"domain": ".github.com",
"path": "/",
"secure": true,
"httpOnly": true,
"sameSite": "lax",
"expirationDate": 1768848000
},
"user_session": {
"value": "ABC123XYZ789...",
"domain": ".github.com",
"path": "/",
"secure": true,
"httpOnly": true,
"sameSite": "lax",
"expirationDate": 1768848000
}
}
}
Fields:
syncKeys: Array of cookie names to sync. Empty [] means sync all cookies in the file.cookies: Key-value pairs where cookie name is the key.httpOnly flag may have restrictionshttpOnly cookies may not be accessible depending on browser/extension permissionsMIT License - Free to use and modify.
Array.from()