mirror of
https://github.com/kccleoc/seedpgp-web.git
synced 2026-03-06 17:37:51 +08:00
877 lines
23 KiB
Markdown
877 lines
23 KiB
Markdown
# SeedPGP v1.4.7
|
||
|
||
**Secure BIP39 mnemonic backup using PGP encryption and QR codes**
|
||
|
||
A client-side web app for encrypting cryptocurrency seed phrases with OpenPGP and encoding them as QR-friendly Base45 frames. Designed for offline use on TailsOS with built-in security verification.
|
||
|
||
**Live Demo (Testing Only):** <https://seedpgp-web.pages.dev>
|
||
|
||
---
|
||
|
||
## 🚦 Quick Start — Recommended TailsOS Workflow
|
||
|
||
For **real funds** ($100+), follow this airgapped TailsOS workflow:
|
||
|
||
```bash
|
||
# 1. Boot TailsOS (airgapped - no network!)
|
||
# 2. Open Terminal and run:
|
||
git clone https://github.com/kccleoc/seedpgp-web.git
|
||
cd seedpgp-web
|
||
|
||
# 3. Build and verify (single command)
|
||
make full-build-tails
|
||
|
||
# 4. Serve locally in Tor Browser
|
||
make serve-local
|
||
# → Open http://localhost:8000 in Tor Browser
|
||
```
|
||
|
||
**That's it.** The Makefile handles everything: build, CSP injection, integrity verification, and security auditing.
|
||
|
||
---
|
||
|
||
## 💡 Security-First Usage Guide
|
||
|
||
| Your Fund Size | Recommended Setup | Build Command | Time |
|
||
|----------------|-------------------|---------------|------|
|
||
| **Testing** (<$100) | Any computer, local mode | `make build-offline` | 5 min |
|
||
| **Real Use** ($100–$10K) | Clean computer, network disabled | `make build-offline` | 15 min |
|
||
| **Serious** ($10K–$100K) | **TailsOS or Ubuntu Live (airgapped)** | `make full-build-tails` | 30 min |
|
||
| **Vault** (>$100K) | TailsOS + hardware wallet + multisig | `make full-build-tails` | 1+ hour |
|
||
|
||
**The more funds at stake, the more security precautions you take.**
|
||
|
||
**Note:** TailsOS and Ubuntu Live USB provide equivalent security for offline seed operations. See Path 1 (TailsOS) and Path 3 (Ubuntu Live) below for detailed workflows.
|
||
|
||
---
|
||
|
||
## 🔧 Makefile Commands Reference
|
||
|
||
### Core Build Commands
|
||
|
||
```bash
|
||
# Install dependencies
|
||
make install
|
||
|
||
# Build for Cloudflare Pages (production)
|
||
make build
|
||
|
||
# Build for offline local testing
|
||
make build-offline
|
||
|
||
# Build for TailsOS with embedded CSP + integrity checks
|
||
make build-tails
|
||
|
||
# Full TailsOS pipeline (recommended for real use)
|
||
make full-build-tails
|
||
```
|
||
|
||
### Testing & Verification
|
||
|
||
```bash
|
||
# Verify TailsOS build integrity (CSP, checksums, paths)
|
||
make verify-tails
|
||
|
||
# Verify offline compatibility
|
||
make verify-offline
|
||
|
||
# Run security audit
|
||
make audit
|
||
|
||
# Run test suite
|
||
make test
|
||
```
|
||
|
||
### Local Servers
|
||
|
||
```bash
|
||
# Serve with Python HTTP server
|
||
make serve-local
|
||
|
||
# Serve with Bun server
|
||
make serve-bun
|
||
|
||
# Development mode (hot reload)
|
||
make dev
|
||
```
|
||
|
||
### Utility
|
||
|
||
```bash
|
||
# Clean build artifacts
|
||
make clean
|
||
|
||
# Show all available commands
|
||
make help
|
||
```
|
||
|
||
---
|
||
|
||
## 🛡️ Path 1: TailsOS Airgapped Setup (RECOMMENDED for $10K+)
|
||
|
||
This is the **gold standard** for seed phrase management. Takes 30 minutes, provides maximum security.
|
||
|
||
### Why TailsOS?
|
||
|
||
- **Amnesic**: Runs entirely in RAM, leaves no trace on disk
|
||
- **Airgapped**: You physically disconnect from all networks
|
||
- **Isolated**: Browser can't access persistent storage
|
||
- **Audited**: Open-source OS trusted by journalists and activists
|
||
|
||
### Step 1: Prepare TailsOS USB
|
||
|
||
```bash
|
||
# On your primary computer:
|
||
|
||
# 1. Download Tails ISO
|
||
# Visit: https://tails.net/install/
|
||
# Download latest version (verify signature!)
|
||
|
||
# 2. Burn to USB stick
|
||
# Use Balena Etcher or dd command
|
||
# Minimum 8GB USB required
|
||
|
||
# 3. Label this USB "TAILS SEED OPS"
|
||
# Keep separate from daily-use USBs
|
||
```
|
||
|
||
### Step 2: Boot TailsOS (Airgapped)
|
||
|
||
```bash
|
||
# Physical security checklist:
|
||
□ Unplug Ethernet cable from computer
|
||
□ Disable WiFi in BIOS (if possible)
|
||
□ Put phone in airplane mode (away from desk)
|
||
□ Close curtains (prevent shoulder surfing)
|
||
|
||
# Boot process:
|
||
1. Insert TailsOS USB
|
||
2. Reboot computer
|
||
3. Press F12/ESC/DEL to enter boot menu
|
||
4. Select USB drive
|
||
5. Choose "Start Tails"
|
||
6. ⚠️ DO NOT configure WiFi when prompted
|
||
7. Verify network icon shows "disconnected"
|
||
```
|
||
|
||
### Step 3: Build SeedPGP on TailsOS
|
||
|
||
```bash
|
||
# Open Terminal (Applications → System Tools → Terminal)
|
||
|
||
# Install Bun (first time only)
|
||
curl -fsSL https://bun.sh/install | bash
|
||
source ~/.bashrc
|
||
|
||
# Clone repository
|
||
git clone https://github.com/kccleoc/seedpgp-web.git
|
||
cd seedpgp-web
|
||
|
||
# Install dependencies
|
||
make install
|
||
|
||
# Build with security hardening
|
||
make full-build-tails
|
||
```
|
||
|
||
**Note:** All builds include a baseline CSP in index.html, but the `make full-build-tails` pipeline injects a stricter, WASM-compatible CSP tailored for TailsOS.
|
||
|
||
**What `make full-build-tails` does:**
|
||
|
||
1. **Cleans** all previous build artifacts
|
||
2. **Builds** with relative paths for offline use
|
||
3. **Injects** CSP meta tag directly into HTML
|
||
4. **Creates** `dist-tails/` directory with:
|
||
- Complete app bundle
|
||
- `README.txt` with SHA-256 checksums
|
||
- Security documentation
|
||
5. **Verifies** CSP enforcement, relative paths, integrity
|
||
6. **Audits** for network calls, external URLs, security issues
|
||
|
||
### Step 4: Verify Build Integrity
|
||
|
||
The build process automatically verifies:
|
||
|
||
```bash
|
||
✅ CSP enforces connect-src 'none' (all network calls blocked)
|
||
✅ Relative paths detected (offline compatible)
|
||
✅ No suspicious external domains
|
||
ℹ️ fetch() references exist in bundle (from openpgp.js)
|
||
✓ These are BLOCKED by CSP connect-src 'none' at runtime
|
||
✅ TailsOS build verification complete
|
||
```
|
||
|
||
**Security Note:** `fetch()` and `XMLHttpRequest` references exist in the bundle (from OpenPGP.js library code), but they are **completely blocked** by CSP `connect-src 'none'` at the browser level. The verification confirms CSP enforcement, not the absence of dead code.
|
||
|
||
### Step 5: Serve Locally in Tor Browser
|
||
|
||
```bash
|
||
# Start local HTTP server
|
||
make serve-local
|
||
|
||
# Output:
|
||
# 🚀 Starting local server at http://localhost:8000
|
||
# Press Ctrl+C to stop
|
||
```
|
||
|
||
**Open Tor Browser** (pre-installed in TailsOS):
|
||
|
||
1. Launch Tor Browser from desktop
|
||
2. Navigate to: `http://localhost:8000`
|
||
3. App loads — all processing happens locally
|
||
4. Verify "Network BLOCKED" indicator in app header
|
||
|
||
### Step 6: Use SeedPGP Securely
|
||
|
||
Now proceed to "Using SeedPGP" section below. All entropy generation, encryption, and QR generation happens offline in your browser's memory.
|
||
|
||
**When finished:**
|
||
|
||
```bash
|
||
# Stop server (Ctrl+C in Terminal)
|
||
# Shutdown TailsOS (Applications → Shutdown)
|
||
# ✅ All data erased from RAM
|
||
# ✅ No trace left on computer
|
||
```
|
||
|
||
---
|
||
|
||
## 🏠 Path 2: Local Offline Setup (Acceptable for <$10K)
|
||
|
||
For smaller amounts, you can run on a regular computer with network disabled.
|
||
|
||
```bash
|
||
# Clone repository
|
||
git clone https://github.com/kccleoc/seedpgp-web.git
|
||
cd seedpgp-web
|
||
|
||
# Install dependencies
|
||
make install
|
||
|
||
# Build for offline use
|
||
make full-build-offline
|
||
|
||
# Disconnect network NOW:
|
||
# - Unplug Ethernet
|
||
# - Disable WiFi
|
||
# - Airplane mode ON
|
||
|
||
# Serve locally
|
||
make serve-local
|
||
|
||
# Open browser: http://localhost:8000
|
||
```
|
||
|
||
**Security vs TailsOS:**
|
||
|
||
| Feature | Local Offline | TailsOS Airgapped |
|
||
|---------|---------------|-------------------|
|
||
| RAM-only execution | ❌ No | ✅ Yes |
|
||
| Disk trace | ⚠️ Possible | ✅ None |
|
||
| Extension isolation | ⚠️ Manual | ✅ Automatic |
|
||
| Memory dump protection | ❌ Limited | ✅ Strong |
|
||
| **Best for** | Testing, <$10K | $10K+, serious use |
|
||
|
||
---
|
||
|
||
## 🐧 Path 3: Ubuntu Live USB (Alternative to TailsOS)
|
||
|
||
**Ubuntu Live USB provides equivalent security to TailsOS** for offline seed operations. It's RAM-only, amnesic (data erased on shutdown), and may be more familiar if you're already comfortable with Ubuntu.
|
||
|
||
### When to Use Ubuntu Live USB
|
||
|
||
- ✅ You're already familiar with Ubuntu/Linux workflows
|
||
- ✅ You only need offline operations (no Tor required)
|
||
- ✅ You want faster boot time (~1 min vs Tails ~2 min)
|
||
- ✅ You might need to install additional tools during the session
|
||
|
||
### Security Properties
|
||
|
||
| Feature | Ubuntu Live USB | TailsOS |
|
||
|---------|-----------------|---------|
|
||
| RAM-only execution | ✅ Yes | ✅ Yes |
|
||
| Amnesic (data erased on poweroff) | ✅ Yes | ✅ Yes |
|
||
| Network isolation | ⚠️ Manual disable | ✅ Automatic (Tor-only) |
|
||
| Pre-installed crypto tools | ❌ Need Python | ✅ GPG, KeePassXC built-in |
|
||
| Boot time | ~1 min | ~2 min |
|
||
| Best for | Offline seed ops | Offline + Tor workflows |
|
||
|
||
**For your use case (offline seed blending): Both are equivalent.**
|
||
|
||
---
|
||
|
||
### Step 1: Prepare Ubuntu Live USB
|
||
|
||
**On your regular computer:**
|
||
|
||
```bash
|
||
# Download Ubuntu Desktop LTS ISO
|
||
wget https://releases.ubuntu.com/24.04/ubuntu-24.04-desktop-amd64.iso
|
||
|
||
# Verify SHA256 checksum
|
||
sha256sum ubuntu-24.04-desktop-amd64.iso
|
||
# Compare against official checksum from ubuntu.com/download
|
||
|
||
# Create bootable USB (Linux/Mac)
|
||
sudo dd if=ubuntu-24.04-desktop-amd64.iso of=/dev/sdX bs=4M status=progress
|
||
# ⚠️ Replace /dev/sdX with your USB device (check with 'lsblk')
|
||
|
||
# Windows: Use Rufus or balenaEtcher instead
|
||
```
|
||
|
||
**Prepare SeedPGP on a separate USB drive:**
|
||
|
||
```bash
|
||
# Clone and build on your trusted computer
|
||
git clone https://github.com/kccleoc/seedpgp-web.git
|
||
cd seedpgp-web
|
||
make install
|
||
make full-build-tails # Creates dist-tails/ with embedded CSP
|
||
|
||
# Generate checksum file
|
||
cd dist-tails
|
||
sha256sum index.html > CHECKSUM.txt
|
||
cd ..
|
||
|
||
# Copy to second USB drive (label it "SEEDPGP-OFFLINE")
|
||
cp -r dist-tails/ /media/your-usb/seedpgp-offline/
|
||
```
|
||
|
||
**You now have:**
|
||
1. **USB #1:** Ubuntu Live bootable installer
|
||
2. **USB #2:** Pre-verified SeedPGP build with checksums
|
||
|
||
---
|
||
|
||
### Step 2: Boot Ubuntu Live (Network Disabled)
|
||
|
||
**Physical security checklist:**
|
||
|
||
```
|
||
□ Unplug Ethernet cable from computer
|
||
□ Remove SIM card (if using a laptop with cellular)
|
||
□ Put phone in airplane mode (away from desk)
|
||
□ Close curtains (prevent shoulder surfing)
|
||
```
|
||
|
||
**Boot process:**
|
||
|
||
1. Insert Ubuntu Live USB (#1)
|
||
2. Reboot computer and press **F12/F2/ESC** during startup
|
||
3. Select USB drive from boot menu
|
||
4. Choose **"Try Ubuntu"** (NOT "Install Ubuntu")
|
||
5. **IMMEDIATELY after desktop loads:** Click network icon → **Disable Wi-Fi**
|
||
6. Verify network status in terminal:
|
||
|
||
```bash
|
||
ip link show
|
||
# All interfaces should show 'state DOWN' except 'lo' (loopback)
|
||
|
||
# Confirm no external routes
|
||
ip route
|
||
# Should ONLY show: 127.0.0.0/8 dev lo
|
||
```
|
||
|
||
---
|
||
|
||
### Step 3: Verify Clean State
|
||
|
||
```bash
|
||
# Open Terminal (Ctrl+Alt+T)
|
||
|
||
# Check no mounted writable drives
|
||
mount | grep -v "ro,"
|
||
# Should only show read-only mounts (iso9660, squashfs)
|
||
|
||
# Check no swap space
|
||
swapon --show
|
||
# Should return nothing
|
||
|
||
# Verify RAM usage
|
||
free -h
|
||
# Should show ~2-4GB used (OS running entirely in RAM)
|
||
```
|
||
|
||
---
|
||
|
||
### Step 4: Load and Verify SeedPGP
|
||
|
||
```bash
|
||
# Insert USB #2 (SEEDPGP-OFFLINE)
|
||
# It will auto-mount to /media/ubuntu/SEEDPGP-OFFLINE or similar
|
||
|
||
# Navigate to the build folder
|
||
cd /media/ubuntu/*/seedpgp-offline/
|
||
# Or use: cd /media/ubuntu/SEEDPGP-OFFLINE/seedpgp-offline/
|
||
|
||
# Verify integrity before running
|
||
sha256sum -c CHECKSUM.txt
|
||
# Should output: index.html: OK
|
||
|
||
# If verification fails → STOP! Do not proceed.
|
||
# Re-build on your trusted computer and copy again.
|
||
```
|
||
|
||
---
|
||
|
||
### Step 5: Serve Locally with Python
|
||
|
||
**Important:** You cannot open `file://` URLs directly in modern browsers due to CORS restrictions. You must serve over HTTP on localhost.
|
||
|
||
```bash
|
||
# Start Python HTTP server (Python 3 is pre-installed)
|
||
python3 -m http.server 8000 &
|
||
# The '&' runs it in background
|
||
|
||
# You'll see:
|
||
# Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
|
||
```
|
||
|
||
**Security verification: Localhost is safe**
|
||
|
||
Even though the server listens on `0.0.0.0:8000` (all interfaces), there are **no active network interfaces** to reach it from outside:
|
||
|
||
```bash
|
||
# Verify localhost-only access
|
||
sudo ss -tlnp | grep 8000
|
||
# Shows: LISTEN 0.0.0.0:8000 (looks exposed, but...)
|
||
|
||
# Check which interfaces exist
|
||
ip addr show
|
||
# Should ONLY show 'lo' (loopback 127.0.0.1) with status UP
|
||
# No eth0, wlan0, or other interfaces should be UP
|
||
|
||
# Try accessing from "outside" (this should fail)
|
||
curl http://192.168.1.100:8000 # Use any typical LAN IP
|
||
# Should instantly fail: "Network unreachable"
|
||
```
|
||
|
||
**The key:** Even though Python binds to `0.0.0.0`, there are no physical network paths to reach it. Localhost is a kernel-internal loopback interface.
|
||
|
||
---
|
||
|
||
### Step 6: Open in Firefox
|
||
|
||
```bash
|
||
# Launch Firefox with localhost URL
|
||
firefox http://localhost:8000 &
|
||
```
|
||
|
||
**Verify the app loaded correctly:**
|
||
|
||
1. SeedPGP interface appears
|
||
2. Check browser console (F12) for CSP enforcement:
|
||
- Should see no CSP violation errors
|
||
- Network tab should show only localhost requests
|
||
3. Verify "Network BLOCKED" indicator in app header
|
||
|
||
---
|
||
|
||
### Step 7: Use SeedPGP
|
||
|
||
Now proceed with your seed operations (see "Using SeedPGP: The Workflow" section below):
|
||
|
||
- Generate entropy (dice rolls recommended)
|
||
- Blend multiple hardware wallet seeds (if applicable)
|
||
- Encrypt to PGP key or password
|
||
- Export QR backup
|
||
- **Write final seed to paper immediately**
|
||
|
||
**⚠️ CRITICAL:** Never save anything to disk. All data stays in RAM.
|
||
|
||
---
|
||
|
||
### Step 8: Shutdown and Verify Data Erasure
|
||
|
||
```bash
|
||
# Stop the Python server (not strictly necessary, but good practice)
|
||
killall python3
|
||
|
||
# Power off Ubuntu Live
|
||
sudo poweroff
|
||
|
||
# Physical verification:
|
||
□ Remove both USB drives
|
||
□ All RAM contents are erased (power loss = data loss)
|
||
□ No trace left on computer's hard drive
|
||
```
|
||
|
||
**What just happened:**
|
||
|
||
- ✅ All seed operations occurred in RAM only
|
||
- ✅ Python HTTP server never had external network access
|
||
- ✅ SeedPGP never wrote to persistent storage
|
||
- ✅ Shutdown wiped all RAM contents
|
||
- ✅ Computer's hard drive was never touched (read-only boot)
|
||
|
||
---
|
||
|
||
### Optional: Advanced Hardening
|
||
|
||
If you want to match TailsOS-level security:
|
||
|
||
**1. Disable swap (already disabled by default, but verify):**
|
||
```bash
|
||
sudo swapoff -a
|
||
```
|
||
|
||
**2. Clear clipboard before shutdown:**
|
||
```bash
|
||
# If you copied anything sensitive
|
||
echo "" | xclip -selection clipboard
|
||
```
|
||
|
||
**3. Wipe RAM on shutdown (paranoid mode):**
|
||
```bash
|
||
# For protection against cold-boot attacks (freezing RAM with liquid nitrogen)
|
||
sudo apt install secure-delete
|
||
sudo sdmem -v # Takes ~2 min, overwrites RAM with random data
|
||
```
|
||
|
||
**Note:** For your threat model (protecting seeds from remote attackers, not physical access to frozen RAM), step 3 is unnecessary.
|
||
|
||
---
|
||
|
||
### Ubuntu Live vs TailsOS: Summary
|
||
|
||
**Use Ubuntu Live USB if:**
|
||
- You're already comfortable with Ubuntu
|
||
- You only need offline seed operations
|
||
- You want faster boot time
|
||
- You value familiarity over maximum security
|
||
|
||
**Use TailsOS if:**
|
||
- You want zero-config maximum security
|
||
- You might need Tor for other operations
|
||
- You're handling $100K+ and want the most audited option
|
||
- You want automatic MAC randomization and anti-forensics
|
||
|
||
**For your use case (three-hardware-wallet blend on Ubuntu Live): ✅ Perfectly safe.**
|
||
|
||
---
|
||
|
||
## 🔐 Using SeedPGP: The Workflow
|
||
|
||
### Step 1: Generate Entropy (New Seed)
|
||
|
||
SeedPGP offers multiple entropy sources you can combine:
|
||
|
||
```bash
|
||
🎲 Dice Rolls - Physical randomness (99 rolls recommended)
|
||
🎥 Camera Noise - Visual entropy from textured surfaces
|
||
🎵 Audio Input - Microphone randomness from ambient sound
|
||
```
|
||
|
||
**Recommended: Dice Rolls (Highest Trust)**
|
||
|
||
1. Click **"Create"** tab → **"Dice Rolls"**
|
||
2. Roll physical dice 99 times
|
||
3. Enter each result (1-6)
|
||
4. App shows entropy progress bar
|
||
5. Click **"Generate Seed"**
|
||
6. **Your 12 or 24-word mnemonic appears**
|
||
|
||
**⚠️ CRITICAL:** Write down seed phrase on paper RIGHT NOW. Don't trust digital storage.
|
||
|
||
### Step 2: Encrypt Your Seed
|
||
|
||
**Option A: Password-Based Encryption (Simplest)**
|
||
|
||
```bash
|
||
1. Your seed phrase is visible in the textarea
|
||
2. Enter a strong password (25+ characters):
|
||
Example: "Tr0pic!M0nkey$Orange#2024@Secret%Phrase"
|
||
3. Confirm password
|
||
4. Click "Generate QR Backup"
|
||
5. Screenshot or print the QR code
|
||
```
|
||
|
||
**Option B: PGP Key Encryption (Most Secure)**
|
||
|
||
```bash
|
||
# Prerequisites: Have a PGP keypair (generate with GPG)
|
||
gpg --full-generate-key # Follow prompts
|
||
gpg --armor --export your-email@example.com > public.asc
|
||
|
||
# In SeedPGP:
|
||
1. Click "PGP Key Input"
|
||
2. Paste your public key
|
||
3. App shows fingerprint → verify it matches
|
||
4. Click "Use This Key"
|
||
5. Click "Generate QR Backup"
|
||
6. Save QR code securely
|
||
```
|
||
|
||
### Step 3: Test Recovery IMMEDIATELY
|
||
|
||
**⚠️ DO NOT SKIP THIS STEP**
|
||
|
||
```bash
|
||
1. Click "Restore" tab
|
||
2. Scan or upload your QR backup
|
||
3. Enter password OR provide private key
|
||
4. Verify decrypted seed matches original
|
||
5. If mismatch → ⚠️ DO NOT USE, redo backup
|
||
```
|
||
|
||
**Why test?** Better to find a corrupt backup now than during an emergency.
|
||
|
||
### Step 4: Store Backups Securely
|
||
|
||
You now have:
|
||
|
||
- ✅ **Paper seed** (12/24 words handwritten)
|
||
- ✅ **Encrypted QR code** (digital backup)
|
||
|
||
**Storage strategy:**
|
||
|
||
| Item | Location | Redundancy |
|
||
|------|----------|------------|
|
||
| Paper seed | Safe deposit box | Primary copy |
|
||
| Paper seed copy 2 | Home safe | Backup copy |
|
||
| QR code | USB drive in safe | Digital recovery |
|
||
| QR code copy 2 | Cloud storage (encrypted!) | Disaster recovery |
|
||
| Password/PGP key | Password manager | Encrypted separately |
|
||
|
||
**Geographic distribution:** Keep copies in different physical locations (home, office, bank vault).
|
||
|
||
---
|
||
|
||
## 🧪 Development & Testing
|
||
|
||
### Run Tests
|
||
|
||
```bash
|
||
# All tests
|
||
make test
|
||
|
||
# Individual test suites
|
||
bun test src/lib/bip39.test.ts
|
||
bun test src/lib/seedpgp.test.ts
|
||
bun test src/lib/krux.test.ts
|
||
```
|
||
|
||
### Development Mode
|
||
|
||
```bash
|
||
# Hot reload development server
|
||
make dev
|
||
|
||
# With network blocking enabled by default
|
||
VITE_NETWORK_BLOCK=true make dev
|
||
```
|
||
|
||
### Security Auditing
|
||
|
||
```bash
|
||
# Full security audit
|
||
make audit
|
||
|
||
# Output includes:
|
||
# - CSP configuration check
|
||
# - Network API usage analysis
|
||
# - Persistent storage detection
|
||
# - eval()/Function() detection
|
||
# - Defense-in-depth layer summary
|
||
```
|
||
|
||
---
|
||
|
||
## 🏗️ Build Artifacts Explained
|
||
|
||
### `make build-tails` Output
|
||
|
||
```
|
||
dist-tails/
|
||
├── index.html # CSP injected, relative paths
|
||
├── assets/
|
||
│ ├── index-*.js # Main bundle (minified)
|
||
│ ├── index-*.css # Styles
|
||
│ └── secp256k1.wasm # Crypto library
|
||
└── README.txt # SHA-256 checksums + usage instructions
|
||
```
|
||
|
||
### CSP Configuration (Embedded in HTML)
|
||
|
||
```html
|
||
<meta http-equiv="Content-Security-Policy"
|
||
content="default-src 'self';
|
||
script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval';
|
||
style-src 'self' 'unsafe-inline';
|
||
img-src 'self' data: blob:;
|
||
connect-src 'none';
|
||
font-src 'self';
|
||
object-src 'none';
|
||
base-uri 'self';
|
||
form-action 'none';"
|
||
data-env="tails">
|
||
```
|
||
|
||
**Key directive:** `connect-src 'none'` — Browser refuses ALL network requests (fetch, XHR, WebSocket, etc.)
|
||
|
||
---
|
||
|
||
## 🛡️ Security Architecture
|
||
|
||
### Defense-in-Depth Layers
|
||
|
||
| Layer | Mechanism | Bypassable? | Purpose |
|
||
|-------|-----------|-------------|---------|
|
||
| **1. CSP** | `connect-src 'none'` in HTML | ❌ No (browser enforced) | **PRIMARY DEFENSE** |
|
||
| 2. Network Blocker | JS patches window.fetch/XHR | ✅ Yes (console bypass) | Defense-in-depth |
|
||
| 3. Airgapped OS | TailsOS, no network drivers | ❌ No (physical isolation) | Ultimate isolation |
|
||
| 4. Session Crypto | AES-256-GCM, non-exportable | ⚠️ Memory dumps | Protects cached data |
|
||
| 5. Auto-Clear | 10s clipboard wipe | ✅ Yes (user can cancel) | Reduces exposure window |
|
||
|
||
**Primary Security:** CSP + TailsOS = two independent layers that must BOTH fail for compromise.
|
||
|
||
### Threat Model
|
||
|
||
**What SeedPGP Protects Against:**
|
||
|
||
✅ Browser extensions stealing seed
|
||
✅ Malicious websites accessing clipboard
|
||
✅ Network exfiltration attempts
|
||
✅ Accidental data leaks to localStorage
|
||
✅ Session replay attacks
|
||
|
||
**What SeedPGP CANNOT Protect Against:**
|
||
|
||
❌ Compromised TailsOS ISO (verify signatures!)
|
||
❌ Hardware keyloggers
|
||
❌ Evil maid attacks (physical device tampering)
|
||
❌ Memory dumps from privileged malware
|
||
❌ Social engineering (phishing for password)
|
||
|
||
**Mitigation:** Use TailsOS (verified ISO) + physical security + test recovery immediately.
|
||
|
||
---
|
||
|
||
## 📖 Technical Documentation
|
||
|
||
- [MEMORY_STRATEGY.md](doc/MEMORY_STRATEGY.md) - Why JS can't zero memory, defense strategies
|
||
- [RECOVERY_PLAYBOOK.md](doc/RECOVERY_PLAYBOOK.md) - Offline recovery procedures
|
||
- [TAILS_OFFLINE_PLAYBOOK.md](doc/TAILS_OFFLINE_PLAYBOOK.md) - Complete TailsOS workflow
|
||
- [SeedPGP-Web-Forensic-Security-Report.pdf](doc/) - Independent security audit
|
||
|
||
---
|
||
|
||
## 🆘 Troubleshooting
|
||
|
||
### Build Issues
|
||
|
||
```bash
|
||
# Permission denied during build
|
||
sudo chmod +x Makefile
|
||
make clean && make install
|
||
|
||
# Bun not found
|
||
curl -fsSL https://bun.sh/install | bash
|
||
source ~/.bashrc
|
||
|
||
# CSP not embedded
|
||
make clean build-tails
|
||
grep "Content-Security-Policy" dist-tails/index.html
|
||
```
|
||
|
||
### TailsOS Issues
|
||
|
||
```bash
|
||
# Can't access localhost:8000
|
||
# → Check firewall: sudo ufw allow 8000
|
||
# → Use 127.0.0.1:8000 instead
|
||
|
||
# Bun installation fails
|
||
# → TailsOS persistence required
|
||
# → Use temporary session, re-install each boot
|
||
|
||
# Camera/microphone not working
|
||
# → TailsOS may block by default
|
||
# → Use dice rolls instead (recommended anyway)
|
||
```
|
||
|
||
### Recovery Issues
|
||
|
||
```bash
|
||
# QR scan fails
|
||
# → Ensure good lighting, steady camera
|
||
# → Upload image file instead of scanning
|
||
|
||
# Decryption fails
|
||
# → Verify password exactly matches
|
||
# → Check PGP key fingerprint
|
||
# → QR may be damaged → test backup immediately after creation!
|
||
```
|
||
|
||
---
|
||
|
||
## ⚖️ License & Disclaimer
|
||
|
||
**MIT License** - See LICENSE file
|
||
|
||
**⚠️ CRITICAL DISCLAIMER:**
|
||
|
||
```
|
||
CRYPTOCURRENCY SECURITY IS YOUR RESPONSIBILITY.
|
||
|
||
This software is provided "AS IS", without warranty of any kind.
|
||
|
||
1. TEST with small amounts ($1-10) before trusting with real funds
|
||
2. VERIFY recovery works immediately after creating backup
|
||
3. STORE multiple copies in geographically distributed locations
|
||
4. USE TailsOS for amounts > $10K
|
||
5. CONSULT professional security advice for amounts > $100K
|
||
|
||
Your seed phrase = your funds. Lose the seed = lose the funds.
|
||
The author is NOT responsible for:
|
||
- Lost funds due to bugs, user error, or hardware failure
|
||
- Compromised devices or insecure storage
|
||
- Forgotten passwords or lost backups
|
||
|
||
If you don't understand how this works, start with $10 and test thoroughly.
|
||
```
|
||
|
||
---
|
||
|
||
## 🙏 Credits & Security
|
||
|
||
**Author:** kccleoc
|
||
**Security Audit:** v1.4.7 (February 2026) - No exploits found
|
||
**License:** MIT
|
||
|
||
**Report Security Issues:**
|
||
|
||
- Private disclosure via [GitHub Security Advisory](https://github.com/kccleoc/seedpgp-web/security)
|
||
- For urgent issues: Encrypt with PGP key in repository
|
||
|
||
**Dependencies Audited:**
|
||
|
||
- OpenPGP.js v5.11+
|
||
- BIP39 reference implementation
|
||
- jsQR for QR scanning
|
||
- secp256k1 WASM module
|
||
|
||
---
|
||
|
||
## 🚀 Quick Reference Card
|
||
|
||
```bash
|
||
# === PRODUCTION WORKFLOW (TailsOS) ===
|
||
make full-build-tails # Build + verify + audit
|
||
make serve-local # Serve on localhost:8000
|
||
|
||
# === DEVELOPMENT ===
|
||
make dev # Hot reload
|
||
make test # Run tests
|
||
make audit # Security audit
|
||
|
||
# === VERIFICATION ===
|
||
make verify-tails # Check CSP, checksums, paths
|
||
grep "connect-src" dist-tails/index.html # Manual CSP check
|
||
|
||
# === CLEANUP ===
|
||
make clean # Remove all build artifacts
|
||
```
|
||
|
||
**Remember:** More funds = more security steps. Don't skip TailsOS for serious amounts.
|