LiveSecret is a Phoenix LiveView web application built for secure sharing of passwords or other secrets. The secret content is End-to-End Encrypted using your browser's built-in cryptography library, SubtleCrypto.
Because encryption is done within the browser, LiveSecret relies on the physical security of the user's personal computer or mobile device. You should only use LiveSecret from a trusted endpoint, and only if it's hosted by someone you trust.
Also, LiveSecret has not undergone a security audit, so it doesn't provide any guarantees, especially those regarding any technical claims made by the author.
As a user of LiveSecret you alone are responsible for securing secret content.
- End-to-End Encryption with out-of-band key
- Live Presence and Live Secrets
- Burn after reading
- Link expiration
- Admin view
When you author a secret with LiveSecret, it is encrypted within your browser. The ciphertext is written to the server, but the cleartext is only held locally, and it's removed from your browser's memory at some point after the encryption event; the exact timing is dependent on the browser.
LiveSecret always uses a passphrase-like encryption key to encrypt the secret content. When you author a secret, if you don't specifiy a passphrase, one will be generated for you. The passphrase is stored locally in the browser and is never transmitted to the server in any form.
As the author of a secret, you will be required to transmit the passphrase out-of-band with the intended recipient. You're responsible for the method used for this transmission.
Each secret created with LiveSecret has a unique non-enumerable URL. When a someone renders this URL in a browser, a Phoenix LiveView is loaded and the visitor's presence is tracked. All visitors to this page can view the presence of all other users, and metadata is displayed for each including:
- Admin | Recipient
- Peer address and port
- Timestamp of joining | timestamp of leaving
- Locked | Unlocked | Revealed status
The LiveView is updated for all users as the secret is Decrypted and Burned. You never need to refresh the page.
Live mode is for synchronous sharing. When a secret is in Live mode, all users are Locked by default, which means
the LiveSecret server will prevent the ciphertext from being sent to the client. This locks them out from decrypting
the secret even if they know the passphrase. An Admin can unlock a recipient by clicking the Locked
button in the Admin View. When a recipient is Unlocked, they will be prompted for the passphrase, and if correct,
the cleartext content is displayed.
Async mode is for asynchronous sharing. When a secret is in Async mode, all users are Unlocked by default. If an attacker intercepts the URL and passphrase before the secret is burned, they will be able to decrypt the message.
After a successful decryption event, the ciphertext is deleted from the server. This makes it very likely that the cleartext is revealed to exactly 2 people: the author and the receiver. While we can't give a cryptographic guarantee that exactly 2 clients were involved, Live Presence can help to bolster the likelihood. Also, Live-mode Secrets give near-certainty that the cleartext is revealed only to the expected recipient.
Once burned, the URL can still be visited, but there are no actions to be taken by any party. A burned secret is essentially a tombstone.
When you author a secret, you choose the expiration period for all the information stored on the server (ciphertext, iv, and metadata). After the expiration period, all this information will be deleted from the database. If a user visits the URL for this secret after the expiration, they will be informed that the secret does not exist.
The author of the secret can perform a limited set of actions on the secret after creation. This includes:
- Unlocking users in Live Presence
- Burning the secret
- Turning Live mode on or off
The Admin View cannot view or decrypt the ciphertext.
To start the LiveSecret Phoenix server:
- Install dependencies with
mix deps.get
- Install Tailwind CSS with
mix tailwind.install
- Create and migrate your database with
mix ecto.setup
- Start Phoenix endpoint with
mix phx.server
or inside IEx withiex -S mix phx.server
- Run the tests with
mix test
Now you can visit localhost:4000
from your browser.
Please check Phoenix's deployment guides.
If you're using a volume controlled by docker compose, you'll have to create the database manually before running LiveSecret. For example:
cd /var/lib/docker/volumes/livesecret_db-data
sqlite3 _data/livesecret.db "VACUUM;"
chown -R nobody:root _data
There are a few required environment variables when running in production. You can view
fly.toml
in this repo for the values I've used for the demo, but it will be important for
you to set these to values relevant to your deployment:
Standard Phoenix:
DATABASE_PATH
: Path to the sqlite database on the filesystemPHX_HOST
: The hostname that is presented to the user's browserPORT
: The port that Phoenix listens onSECRET_KEY_BASE
: Standard Phoenix env var for encrypting cookie, etc
Unique to LiveSecret:
BEHIND_PROXY
: When"true"
LiveSecret Presence discovers the user's IP address via the configured x-header. It is strongly recommended to use a reverse proxy.REMOTE_IP_HEADER
: The trusted x-header that presents the end user's IP address. It must start with "x-"
- Official website: https://www.phoenixframework.org/
- Guides: https://hexdocs.pm/phoenix/overview.html
- Docs: https://hexdocs.pm/phoenix
- Forum: https://elixirforum.com/c/phoenix-forum
- Source: https://github.com/phoenixframework/phoenix
- JavaScript and LiveView unit tests
- Change "Joined at" to "Joined since" and update incrementing counter