AquaDownload v1.0.0

v1.0.0 · Windows x64 · GPL-3.0

The browser that leaves no plaintext browsing data on your disk.

Built for shared PCs. Browsing sessions stay in memory. Cookies and site data are written only into an AES-256-GCM vault keyed by Argon2id from your master password, and locking wipes that key from memory.

Installer updates itself from GitHub Releases. Not code-signed yet, so SmartScreen asks before the first run.

Aqua on Windows with the New Tab page open: two tabs, the address bar reading Search DuckDuckGo or type a URL, the blocker shield and lock buttons, a clock and shortcut tiles for GitHub, YouTube, Wikipedia and Hacker News.

The problem

On a shared Windows account, a browser profile is open to whoever signs in.

Standard browsers keep history and bookmarks in plaintext files and protect cookies with a key Windows hands to any program running as you. Aqua's profile is one encrypted database that needs your password.

Standard browser profilePowerShell
PS> cd "$env:LOCALAPPDATA\Google\Chrome\User Data\Default"
PS> ls -Name History, Bookmarks, Network\Cookies
History # SQLite, plaintext URLs, titles, visit times
Bookmarks # JSON, plaintext
Network\Cookies # SQLite, key opened by Windows, no password
PS> sqlite3 History "SELECT url FROM urls LIMIT 3"
https://mail.example.com/u/0/#inbox
https://bank.example.com/accounts
https://github.com/settings/tokens
Aqua profilePowerShell
PS> cd "$env:APPDATA\aqua-browser"
PS> ls -Name aqua.db
aqua.db # SQLite, every row sealed with AES-256-GCM
PS> sqlite3 aqua.db "SELECT hex(value) FROM history LIMIT 1"
01A7F3C95E0B2D88… # format, nonce, tag, ciphertext
PS> sqlite3 aqua.db "SELECT value FROM meta WHERE key='vault'"
{"version":1,"kdf":{"algorithm":"argon2id",…},"wrappedKey":"…"}
# Argon2id salt and the wrapped key; the key itself is never stored

Out of scope

  • Malware running while Aqua is open can read its memory, as with any browser.
  • A keylogger can capture the master password.
  • A weak password can be guessed offline from a copied vault. There is no recovery.

Architecture

Five parts, each one you can audit.

Argon2id encrypted vault

Your password goes through memory-hard Argon2id to unwrap a random data key. Every record in aqua.db is sealed with it. The key is never written to disk and is zeroed when Aqua locks.

  1. master password
  2. Argon2id
  3. key-encryption key
  4. data key
  5. AES-256-GCM rows
KDF
Argon2id · 128 MiB · 4 passes
Cipher
AES-256-GCM, new nonce per write

In-memory sessions

Tab cache, cookies, IndexedDB and service workers live in RAM. Cookies and first-party localStorage are copied into the vault as they change, sealed.
Partition
in-memory
Cookie files
none

Built-in blocker

Ads, trackers and known malware URLs are blocked in every window, private ones included, with scriptlets and element hiding.
Engine
Ghostery adblocker
Lists
uBlock Origin

No telemetry

No analytics, crash reports or user identifiers. The only background requests are the update check and the filter-list refresh.
Update check
at launch
Filter lists
every 4 days

Verified updates

Installed copies download releases from GitHub in the background, differential via blockmaps, and install on quit. Portable copies update by hand.
Integrity
SHA-512, latest.yml
Signing
not yet
Parameters, file formats and every network request in docs/security.md