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
This commit is contained in:
Julius Joska
2026-10-09 14:05:39 +02:00
parent 94cfd72690
commit 00739ac8a0
4 changed files with 75 additions and 5 deletions
+36
View File
@@ -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/), [Keep a Changelog](https://keepachangelog.com/cs/1.1.0/),
verzování dle [ajtak standardu](#verzování). 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 ## [1.2.0] – 2026-10-01
### Nový vzhled ### Nový vzhled
+4 -4
View File
@@ -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. 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 ## 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. - **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. - **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). - **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. - **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. - **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 ## 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 ## License
Šepot is licensed under the **GNU Affero General Public License v3.0** — see [`LICENSE`](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).
+34
View File
@@ -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: <https://sepot.cz/zodpovedne-hlaseni>
- Machine-readable contact: <https://sepot.cz/.well-known/security.txt>
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.
+1 -1
View File
@@ -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 Šepot relies on that stated position and, as an AGPL work, keeps its
complete corresponding source available under the AGPL through channels 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 APK). A written clarification for the current Rust `libsignal` has been
requested from Signal (tracking: <https://github.com/signalapp/libsignal/issues/684>). requested from Signal (tracking: <https://github.com/signalapp/libsignal/issues/684>).