From 00739ac8a08047fabdbfcc80ff3a08639118b43d Mon Sep 17 00:00:00 2001 From: Julius Joska Date: Fri, 9 Oct 2026 14:05:39 +0200 Subject: [PATCH] docs: security policy, accurate push and status notes, unreleased changelog - SECURITY.md with the reporting address and expectations; README points to security@sepot.cz and security.txt - README: FCM is the Android default since 1.2.0 when no UnifiedPush distributor is installed; status reflects the Play release - the "F-Droid" channel is not available yet and is no longer listed - CHANGELOG: unreleased fixes and security hardening --- CHANGELOG.md | 36 ++++++++++++++++++++++++++++++++++++ README.md | 8 ++++---- SECURITY.md | 34 ++++++++++++++++++++++++++++++++++ THIRD-PARTY-NOTICES.md | 2 +- 4 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 SECURITY.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 39d7808..97c9c9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,42 @@ Všechny podstatné změny v aplikaci Šepot. Formát dle [Keep a Changelog](https://keepachangelog.com/cs/1.1.0/), verzování dle [ajtak standardu](#verzování). +## [Nevydáno] + +### Opraveno +- **Hovory se nedaly přijmout.** Příchozí signalizace hovoru se zahazovala dřív, + než se dostala k obsluze hovoru; volaný jen „zazvonil“ z budíčku a pak nic. +- **Obrazovka hovoru po zavěšení:** avatar a jméno uskakovaly vlevo nahoru. +- **Obnova ze 24 slov na novém telefonu** končila nekonečným čekáním — server + odmítal už existující identitu. Nové zařízení ji teď převezme podpisem. +- **Tichá ztráta zpráv:** úklid mizících zpráv mohl přepsat čerstvě přijatou + zprávu; automatický zámek během zpracování zprávy ji mohl nenávratně zahodit; + souběžné šifrování pro téhož příjemce dávalo obálky, které druhá strana + zahodila. Všechny tři cesty opraveny. +- **Velká fronta po delším výpadku** (stovky zpráv) se už neodpojuje v půlce + a server ji po osmi pokusech nemaže. +- **Nátlakový PIN** otevíral relaci se skutečnou identitou, frází i přístupem ke + smazání účtu. Teď je izolovaná: náhodná identita, žádná síť, žádný zásah do + klíčů; smazání v ní nechá skutečný účet být. +- Zvonění z budíčku bez skutečné nabídky končí po 12 s; server budíčky hovoru + omezuje na cíl, takže cizí člověk se znalostí adresy telefon nerozezvoní + pořád dokola. +- Dodatečné odeslání z fronty neztrácí anketu ani zmínky; budíček při + „připojeno“ bez provozu obnoví spojení. + +### Bezpečnost +- Hádání PINu: po pěti chybách prodleva 30 s, dál dvojnásobná až 15 minut. +- Nátlakový a skutečný PIN se ověřují jednou derivací — čas odemčení neprozradí, + který byl zadán. +- Biometrie jen biometricky (zámek telefonu appku neodemkne); zabezpečení + obrazovky je výchozí zapnuté a po odemčení skutečně platí; na iOS klíče + nepřecházejí do iCloud Keychain ani záloh; filtr proti dotykům přes překryvná okna. +- Server: doplňování jednorázových klíčů a rotace podepsaných klíčů + (`POST /v1/keys`), omezení výdeje jednorázových klíčů na adresu, chyby v logu + bez adres push endpointů, připnutí DNS u budíčků, globální strop příloh, + limity délek, `/v1/ready`, uvolnění spojení při vypnutí, revize a zdroj + v `/v1/server-info`. + ## [1.2.0] – 2026-10-01 ### Nový vzhled diff --git a/README.md b/README.md index 11ce8fc..6a3a781 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The design goal is **metadata minimization with a public threat model** — never "zero metadata". The relay is deliberately dumb: it cannot read message content, does not learn who sent a message, and does not log IP addresses. What it *does* see is documented honestly below. -> Status: pre-1.0. The Android client is the primary target; iOS builds run through TestFlight. See [`CHANGELOG.md`](CHANGELOG.md). +> Status: 1.2.x. Android is on Google Play (production 1.1.2, 1.2.0 in internal testing); iOS builds run through TestFlight. See [`CHANGELOG.md`](CHANGELOG.md). ## Features @@ -14,7 +14,7 @@ The design goal is **metadata minimization with a public threat model** — neve - **Group chats** — up to 128 members, pairwise fan-out so every member gets full forward secrecy; the relay never learns a group exists. - **Attachments** — images and files are encrypted client-side (AES-256-GCM) and uploaded as opaque blobs with a TTL; image metadata (EXIF/GPS) is stripped on send. - **Disappearing messages**, read receipts (off by default), voice messages, replies, reactions, edits, contact verification (safety numbers). -- **Push without Google by default** — UnifiedPush/ntfy; FCM (Android) and APNs (iOS) are opt-in. A push wake-up never carries content, sender, or count. +- **Push with or without Google** — UnifiedPush/ntfy when a distributor is installed, otherwise FCM on Android (default since 1.2.0, can be switched off) and APNs on iOS. A push wake-up never carries content, sender, or count. - **Tor transport** (Android, via Orbot) — routes relay traffic over a `.onion` to hide the client IP. Off by default. - **Five languages** — Czech, English, German, Russian, Italian. The UI follows the system language and can be overridden in Settings. @@ -71,10 +71,10 @@ UI strings live in `app/lib/l10n/app_*.arb` (`cs`, `en`, `de`, `ru`, `it`) and a ## Security -Cryptography is implemented by Signal's `libsignal`, not by hand-rolled primitives. If you find a vulnerability, please report it privately to **bezpecnost@sepot.cz** rather than opening a public issue. +Cryptography is implemented by Signal's `libsignal`, not by hand-rolled primitives. If you find a vulnerability, please report it privately to **security@sepot.cz** rather than opening a public issue — see [`SECURITY.md`](SECURITY.md) and [`/.well-known/security.txt`](https://sepot.cz/.well-known/security.txt). ## License Šepot is licensed under the **GNU Affero General Public License v3.0** — see [`LICENSE`](LICENSE). -The license includes an **AGPL §7 additional permission for app-store distribution**: Šepot may be distributed through App Store / Google Play provided the complete corresponding source stays available under the AGPL through a channel *without* those store restrictions (this repository, F-Droid, direct APK). That permission covers only Šepot's own code. The bundled Signal `libsignal` is AGPL-3.0 held by Signal Messenger, LLC — its app-store status is documented in [`THIRD-PARTY-NOTICES.md`](THIRD-PARTY-NOTICES.md). +The license includes an **AGPL §7 additional permission for app-store distribution**: Šepot may be distributed through App Store / Google Play provided the complete corresponding source stays available under the AGPL through a channel *without* those store restrictions (this repository and the direct APK releases). That permission covers only Šepot's own code. The bundled Signal `libsignal` is AGPL-3.0 held by Signal Messenger, LLC — its app-store status is documented in [`THIRD-PARTY-NOTICES.md`](THIRD-PARTY-NOTICES.md). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..fa430a2 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,34 @@ +# Security policy + +## Reporting a vulnerability + +Please report security issues privately — do not open a public issue. + +- E-mail: **security@sepot.cz** +- Web form and policy: +- Machine-readable contact: + +You will get an acknowledgement within 72 hours and a status update at least +every 14 days until the issue is resolved. We aim to ship a fix within 30 days +for issues that affect message confidentiality, authentication, or the relay's +metadata guarantees, and we credit reporters in the changelog unless they +prefer otherwise. + +## Scope + +- the Flutter client (`app/`), including the Signal protocol integration, + local storage (SQLCipher, PIN/biometrics, duress session) and calls; +- the relay (`rust/sepot-relay/`): authentication, routing, push wake-ups, + attachments, rate limiting, TURN credentials; +- the public relay at `relay.sepot.cz` and the website `sepot.cz`. + +Please do not run denial-of-service tests, mass registrations or scans +against the public relay; a local instance (`deploy/relay/`) is enough to +reproduce almost everything. + +## What the relay can and cannot see + +The threat model is documented in the README: the relay sees routing tokens, +message sizes, timing and push tokens, never content or sender identity. +Reports that demonstrate the relay learning more than that are the ones we +care about most. diff --git a/THIRD-PARTY-NOTICES.md b/THIRD-PARTY-NOTICES.md index efb6eed..9995a7d 100644 --- a/THIRD-PARTY-NOTICES.md +++ b/THIRD-PARTY-NOTICES.md @@ -26,7 +26,7 @@ their app-store status is documented in detail below. Šepot relies on that stated position and, as an AGPL work, keeps its complete corresponding source available under the AGPL through channels - without app-store restrictions (this public repository, F-Droid, direct + without app-store restrictions (this public repository, direct APK). A written clarification for the current Rust `libsignal` has been requested from Signal (tracking: ).