Syna icon

Changelog

Mirrored from NUSV/Syna-NUSV · CHANGELOG.md · synced 2026-09-26 11:28 UTC · original on GitHub

All notable changes to Syna — LAN instant messenger (Kotlin Multiplatform + Compose Multiplatform, GPL-3.0). Android · Windows · macOS, fully peer-to-peer, no internet required.

Format: version — date — summary. Releases: GitHub Releases


[1.0.1] — 2026-08-12 — Desktop unlock password (macOS focus)

Added

  • Desktop unlock password (macOS / Windows / Linux): the desktop lock screen previously unlocked with a single click (JVM has no unified biometric API — the lock was UI-only). You can now set a real first-factor password in Settings → Shield; PBKDF2-HMAC-SHA256 (210k iterations, 16-byte salt, constant-time comparison), stored encrypted with atomic writes, wiped on self-destruct. Works standalone or stacked with TOTP as a second factor. Wrong passwords count toward brute-force protection; no recovery by design (documented on the lock screen)

Tests

  • 91 (added desktop password round-trip, controller unlock/brute-force, password+TOTP stacking)

[1.0.0] — 2026-08-12 — Stable: full code review & license audit pass

Stability & correctness (19 issues fixed, verified by a full code review)

  • Outbox no longer drops failed sends: TCP send failures rethrow into the flush loop, so frames stay queued for reconnect instead of being marked "sent" and lost
  • Server recall ownership check fixed: looked up the wrong field (recall frame's own id) — any member could forge recalls; now validated by target message id + sender + group
  • Encrypt-only made complete: mesh group text and 1:1 file transfer no longer fall back to plaintext (queue / wait for key instead); receiver drops plaintext message frames in encrypt-only mode (LAN injection defense)
  • Mesh group file chunks now go to the correct member (member-index misalignment after keyless-member filtering)
  • App upgrades no longer trigger self-destruct: the dex baseline is rewritten on versionCode change (previously any update tripped SHIELD_TAMPERED → data wipe)
  • Session-key rotation hardened: atomic blob writes (crash no longer makes all data undecryptable); the migration key is released only after a successful rewrite
  • Biometric system errors (LOCKOUT/TIMEOUT…) no longer count toward brute-force self-destruct
  • Late-key frames decrypted on pin, epoch recorded only after successful key pin (replay-poisoning of the session epoch closed)
  • Deduped retransmissions re-ACKed (no more stuck SENT/outbox), FILE_CHUNK cross-frame bounds validated, replay window extended to group frames, burn sweep marks cleaned, server group BURN_ACK purge fixed, member public keys validated on the server, server crash auto-restart unblocked, audit-log truncation keeps the hash chain intact, suspicious-module whitelist uses exact names (no evil-linker.so bypass), TOTP waiting screen gained a cancel button (unlock cancel → LOCKED, disable cancel → ARMED, never counts as brute force)
  • Atomic writes everywhere: key pins, master key, identity files; plaintext tmp fallback removed (fail-closed)
  • First-launch wizard persisted; self-destruct also wipes the outbox cache; update checker ignores pre-release tags

License & legal

  • Full license audit: all ~140 runtime dependencies are Apache-2.0 / MIT, all GPL-3.0-compatible — no contamination
  • Dependency vulnerability check (OSV): 0 known vulnerabilities on all direct dependencies
  • Copyright headers: 100% of source files carry the GPL-3.0 SPDX header (94 files); keystore/password confirmed never committed
  • Full audit report: docs/REVISION_AND_LICENSE_AUDIT_v1.0.0.md (English, detailed)

Tests

  • 88 (added TOTP cancel flow tests)

[0.9.9] — 2026-08-11 — RC: forward secrecy, encrypt-only default, storm-tested, UX polish

Security

  • Forward secrecy (process epoch): each process start derives a fresh random epoch; session keys are

derived with base|min(epoch)|max(epoch) — restarting the app rotates all session keys, so a stolen session key cannot decrypt traffic from a previous run; epoch is carried in every encrypted frame

  • Double-try decrypt (new epoch formula → legacy fixed formula fallback): both sides stay symmetric

regardless of key-exchange ordering (works with older peers that don't carry epochs)

  • Encrypt-only is now the default (e2eOnlyEnabled = true): if the peer key isn't ready yet, messages

queue instead of falling back to plaintext; queued messages auto-send when the key arrives

  • No more plaintext fallback in group chats (LAN mesh + server groups): missing member keys → queue +

key exchange request; member copies are skipped instead of sent in the clear

  • Undecryptable frames are never stored as raw ciphertext: if the key frame arrives late (UDP

reordering), the ciphertext is held in a bounded pending queue and decrypted the moment the key is pinned

Stability

  • Outbox cap (500 frames per peer, drops oldest) — no unbounded memory growth for permanently-offline peers
  • 6-engine message storm stress test (86 automated desktop tests total, incl. the storm)

UX

  • Enter to send in the chat input box (IME action Send); Shift+Enter for newline
  • First-launch Shield wizard: 4-step onboarding (biometrics / TOTP / usage / boundaries), skippable
  • Message font size setting (small / medium / large) applied to chat bubbles

Tooling

  • Update checker: silent GitHub Releases check 10 s after launch; only network egress in the app

(the codebase was audited — no backdoors, no hidden endpoints)

  • FAQ_ZH.md; CI gains a dependency-audit job (osv-scanner, non-blocking)

Tests

  • 86

[0.9.8] — 2026-08-10 — JIT false-positive fix, strong-only unlock, signature-learning detection

Fixed

  • ART JIT memfd whitelist (memfd:jit-cache, memfd:jit-zygote-cache) — no more

lock-on-enable for stock devices; non-JIT executable memfd mappings still flagged (multi-dimensional, name-independent)

  • Unlock hardening: biometric prompt requires BIOMETRIC_STRONG only (device-credential

window can no longer auto-pass)

  • Monitor detection: package-fragment list expanded; signature-learning blacklist

— renamed/repackaged monitoring apps are caught by certificate hash; case-insensitive name matching

Tests

  • 84

[0.9.7] — 2026-08-10 — Full review fix release (3rd audit pass)

Critical

  • Shield-off data lockout fixed (native heartbeat check only when armed)
  • Audit-write failure recursion → deferred one-shot escalation
  • TCP heartbeat no longer kills new connections (PONG baseline)
  • Locked-state disk wipe prevented (memory-wiped flag blocks all writes; purge

conditional; rewrite re-verifies)

  • Group-file O(N²) fan-out + REQ_KEY storm fixed (per-member direct send; no REQ_KEY

on foreign ciphertext)

  • Failed-message resend works (send-copy persisted, localPath stored, mime derived)
  • dex hashing actually removed from the light scan (3rd attempt; previous two

silently failed)

Medium

  • serverGroupId stored (disconnect FAILED works); audit truncation re-seals chain;

stealth survives username refresh; BRUTE_FORCE cleared on unlock; self-destruct wipes audit-seen/device baselines; native heartbeat /dev/urandom + monotonic clock; UDP file over TCP; server membership-event & BURN_ACK( receiver) auth; empty-from only for PING; client server-channel read timeout; load synchronized; tmp cleanup; preview rebuild on reload; residual emoji removed; group frames in replay guard; audit never falls back to plaintext

Tests

  • 83

[0.9.6] — 2026-08-10 — Shield self-protection hardening

Added

  • Native heartbeat slot (JVM-hook immune): decrypt path verifies both the JVM and

native heartbeat; hooking JVM beat() can't fake freshness

  • Scanner self-healing: a scan-round exception no longer kills the detection loop
  • Audit-write failure detection: 5 consecutive failed audit writes →

SHIELD_TAMPERED (storage made read-only/filled)

  • Reinstall guard: device-identity change checked independently of Shield state;

reinstall with Shield off → notify to re-enable

Tests

  • 83

[0.9.5] — 2026-08-10 — Image preview, message resend, power-saving discovery, Shield additions

UX

  • Full-screen image preview (tap bubble → fullscreen → tap to close)
  • Resend failed messages (long-press → 重发; burn re-send requires biometric)
  • Voice playback state on the bubble (播放中 / tap to stop)

Power saving

  • Discovery broadcast adapts: 10 fast announcements → 3× slower; incoming/manual refresh resets

Shield

  • DEVICE_CHANGED (LOW): ANDROID_ID vs encrypted baseline (reinstall / backup-restore)
  • Audit-integrity check: audit log deleted/emptied → SHIELD_TAMPERED (审计日志被清除)
  • Decrypt-path probe every 6th decrypt; dex hashing finally moved to the heavy scan

Tests

  • 83

[0.9.4] — 2026-08-10 — Material Icons, Voice Duration, UI Polish

Changed

  • Material icons for send / refresh / play / lock markers (semantic badges stay text: 焚/群主/管理员/禁言/指纹/录音/图片/文件)
  • Voice duration transmitted (FileChunk.durationMs) and shown on the bubble (语音 12秒); filename carries seconds for cross-version display
  • Fixed duplicate "刷新 刷新" label

Tests

  • 82

[0.9.3] — 2026-08-10 — Lock-bypass fix, 2FA enable fix, no-emoji UI, proxy detection

Security fixes

  • Lock bypass closed: clearing a threat while LOCKED no longer auto-returns to

ARMED (previously the app silently unlocked without biometrics when the locking threat disappeared); locked state persists until real verification

  • 2FA enable: stale/corrupt seed files cleared before re-enable; failure now shows a

notice instead of a dead switch

  • No-biometrics devices: unlock taps show a clear notice, never count toward

self-destruct

Changed

  • All emoji removed from the UI (text replacements: 焚/图片/文件/锁/群主/管理员/禁言/播放/录音)
  • Detection: system HTTP proxy (PROXY_SET, LOW advisory) with proxy address detail

Tests

  • 82

[0.9.2] — 2026-08-10 — Group-file encryption, stealth mode, module details

Added

  • Group file transfer E2E-encrypted per member (one ciphertext copy per member,

mesh + server groups; receivers only process decryptable copies) — last plaintext transfer path closed

  • Stealth mode (Settings): stop broadcasting presence (still discover others,

manual refresh still finds you)

  • Group member key fingerprints shown in the administration dialog
  • Suspicious-module detection now reports the actual module paths on the lock

screen and in the audit log

Fixed

  • Suspicious-module whitelist switched to partition prefixes (/system /apex

/vendor /product /system_ext /odm /data/app /data/user) — vendor ROM libraries no longer false-trigger "可疑可执行模块" on first enable

  • Mesh-group file sends silently failed (misdetected as server-group disconnect) —

real fix + regression test

Tests

  • 81 (new: partition whitelist, anonymous-module detection, encrypted group-file

round-trip, stealth announce/stop)

[0.9.1] — 2026-08-10 — Stabilization (full audit pass)

Fixes (full code audit — see SECURITY_AUDIT_REPORT.md)

  • 2FA lockout eliminated — TOTP seed / key pins / audit / fail-counter now use the

master Keystore key (previously session-key encryption made them undecryptable while locked → permanent lockout)

  • Honeypot decoy no longer overwrites real history; burn 60 s TTL fallback actually

works (marker was never written); server-history replay no longer dropped

  • Mesh group file transfer fixed (misdetected as server-group disconnect); ACK

retransmission fixed (counter reset → infinite retransmission; TEXT now ACK/retried)

  • UDP: key exchange uses the real UDP port; 40 KB chunks in UDP mode
  • History-wipe race closed (debounced rewrite vs memory release); burn-purge persists
  • No-biometrics devices no longer count taps as brute-force; interrupted disable flow

can't turn the Shield off; WATCHDOG_TRIP auto-clears on heartbeat recovery

  • Self-destruct order fixed (audit wiped after event, Shield disabled, key pins & voice

cache wiped); screen-capture unregister fixed

  • Group-admin privilege escalation closed (creator protected)
  • Server: zombie-session timeout, kick-all-sessions, server-identity spoofing rejected,

BURN_ACK/RECALL ownership checks, locked history snapshot, immediate burn sweep

  • Burn-send verification failure keeps input; Shield-disabled devices send normally

Added

  • New project logo Syna_logo_2.png (Android launcher all densities + desktop tray)
  • SECURITY_AUDIT_REPORT.md (code review + license audit)
  • License audit: CLEAN — 100% Apache-2.0 deps, no copyleft, all in-tree code original

[0.9.0] — 2026-08-10 — Encrypted file transfer, voice messages, re-auth

Added

  • File transfer E2E encryption (1:1 FILE_CHUNK payloads encrypted; group files documented)
  • Voice messages: long-press 🎤 record (30 s max), encrypted file channel, ▶️ playback; Android AMR-NB / desktop WAV; one-time recording permission
  • Sensitive-operation re-auth: burn-after-reading sends require biometric confirmation
  • Clipboard short TTL: copy action with 30 s auto-clear
  • Server: slow-client isolation (bounded per-session send queue), burn-history 1 h TTL

[0.8.2] — 2026-08-10 — ACK/retransmission, group administration, no-export policy

Added

  • Message-level ACK & retransmission (P2P 1:1; 3 s retry ×3 → offline queue)
  • Group administration: kick / mute (1 h, toggleable) / set-admin; receiver-side

permission checks (forged frames ignored); 👑 ⭐ 🔇 badges

  • No-export policy: android:allowBackup=false; no backup/export features by design
  • Server kick identity fixed (serverId vs groupId — kick notifications were dropped)

[0.8.1] — 2026-08-10 — Key pinning (TOFU), encrypt-only mode, replay defense

Added

  • TOFU key pinning: public keys pinned on first use (encrypted at rest); fingerprint

badge in chat header + full fingerprint for out-of-band verification; key changes rejected → KEY_CHANGED lock; "信任此密钥" re-pin

  • Encrypt-only session mode (refuse plaintext fallback)
  • Replay defense: 10-minute window on real-time frames

[0.8.0] — 2026-08-10 — Deep self-destruct (anti-forensics)

Added

  • SecureWipe: 2-pass random overwrite + fsync on all sensitive files (chat history

incl. .tmp, received files, audit log, TOTP seed, session blob, baselines, crash log)

  • Keystore/TEE storage-key destruction — recovered ciphertext permanently

undecryptable; desktop key file overwritten

  • Audit self-wipe order (event written, then audit file wiped)

[0.7.9] — 2026-08-10 — Active crash defense & permission self-check

Added

  • Native SIGABRT on high-confidence signals (ptrace attach / code or libc hooked) —

no stable debugging window; audit written best-effort before crash

  • Usage-access grant targets Syna (EXTRA_APP_PACKAGE); full permission self-check on

every launch

[0.7.8] — 2026-08-10 — Expanded detection & active countermeasures

Added

  • Riru / EdXposed / TaiChi + SELinux process-domain in root detection
  • IME change / USB attach-detach / suspicious executable module advisories (all LOW)
  • Decrypt-path integrity probing (every ~8th decrypt); watchdog self-healing

(scanner restart); honeypot data pollution (decoy messages)

[0.7.7] — 2026-08-10 — All client bugs fixed

Fixed

  • TCP failure → offline queue (no silent UDP fallback loss); bidirectional heartbeat

(PONG reply + 3-cycle timeout); burn-message TTL fallback with BURN_ACK

  • Server-group disconnect awareness (FAILED status + notification); READ receipts via

server channel; discovery resilience; announcement buffering

  • Quote-bar rendering; image decode off main thread; EDT file dialogs; username-change

discovery restart; duplicate-name file suffixes; CA user-cert-only; mirroring both directions; exact process matching; watchdog alive semantics; AWT listener cleanup

[0.7.6] — 2026-08-10 — Review second pass

Fixed

  • Shield lifecycle on dispose; desktop key quarantine (.corrupt); captureAuth TOCTOU;

native maps buffers 64K/128K; outbox flush mutex; receipt/key-frame send guards; inbound TCP read timeout (90 s); sendText empty guard

[0.7.5] — 2026-08-10 — Full security review fix release

Fixed

  • 2FA bypass closed (no unlock while awaiting code; clearThreat can't skip it);

session-key capture moved after TOTP verification; biometric fail double-count; server relay from forgery; BURN_ACK/RECALL sender validation; FILE_CHUNK bounds + pipeline isolation; TOTP-enable failure guard; DEBUG_MODE downgraded to HIGH; honeypot streak no longer reset; watchdog one-shot trip + restart reset

  • Chat persistence wired (was never injected — chats never survived restarts);

unlock-time rotation order fixed; atomic writes (tmp+rename); CAS StateFlow updates; UDP receive buffer 64 KB; server hardening; macOS close-to-tray fix; tray icon; AWAITING_TOTP code screen visible; version alignment

[0.7.4] — 2026-08-10 — Rotation, unkillable shield, injection traces

Added

  • Session-key rotation per unlock (forward secrecy); dual-factor disable (biometrics +

TOTP — attacker can't turn the shield off); anonymous rwx segment detection (bit2); AWAITING_TOTP lock-screen rendering fix

[0.7.3] — 2026-08-10 — Native anti-hook

Added

  • syscall-direct I/O (GOT/PLT/LD_PRELOAD dead); own-code-segment memory-vs-disk hashing

(inline-hook detection); export-entry self-verification; libc entry verification; integrity bitmask → SHIELD_TAMPERED / FRIDA_DETECTED

[0.7.2] — 2026-08-10 — Native anti-debug (NDK)

Added

  • libsyna_shield.so (C, GPL-3.0, 4 ABIs): TracerPid/maps/threads read in C;

JVM + native dual-channel verification; graceful fallback

[0.7.1] — 2026-08-10 — Data-level key gate

Added

  • Session-key layer wrapped by a biometric-authenticated Keystore key (300 s window) —

no auth event → newly written data unreadable; lock invalidates session; master-key fallback for history (smooth upgrade)

[0.7.0] — 2026-08-10 — TOTP two-factor unlock

Added

  • RFC 6238 dual verification (biometric + 6-digit code); otpauth:// seed import;

wrong codes feed the brute-force pipeline (cooldown + self-destruct)

[0.6.9] — 2026-08-10 — Picker crash fix

Fixed

  • Gallery/file picker crash on all real devices (androidx.activity requestCode ≥ 65536

vs platform 16-bit limit) — fixed requestCode startActivityForResult path

[0.6.8] — 2026-08-09 — Network & screen attack surface

Added

  • Screen capture/recording events (API 34); mirroring change detection; CA-cert & ARP

spoofing detection; SSID fingerprint; Zygisk/Shamiko/LSPosed; SELinux; scan jitter; background memory wipe (60 s); unlock cooldown backoff; downgrade defense

[0.6.7] — 2026-08-09 — Open-source-proof hardening

Added

  • Heartbeat gate (fail-closed decrypt); watchdog ring (3 threads); honeypot fake-lock;

brute-force protection; dex self-verification; key release on lock; live status panel

[0.6.6] — 2026-08-09 — Shield upgrade

Added

  • Single master switch (one tap enables everything); clock-tamper & weak-lock

advisories; Frida port 27043; emulator test-keys; audit encryption at rest

[0.6.5] — 2026-08-08 — Shield single-switch & chat polish

Added / Fixed

  • Quote-preview rework (visible on phone, no overlap on desktop); phone gallery sending

(permission-free); Shield single switch + ◇ title; usage-access guidance (foreground-app sensing); scan cadence split (light 3 s / heavy 15 s)

[0.6.4] — 2026-08-08 — Lock screen redesign

Fixed

  • File-picker click crash defense; crash log dual-write (Download/Syna); lock screen

redesign (pure black / red ◇ / white)

[0.6.3] — 2026-08-08 — Debug-build compatibility

Fixed

  • Debug builds skip signature verification; global crash log for startup debugging

[0.6.2] — 2026-08-08 — Compatibility fix

Fixed

  • Android API 30 credential-detector guard (crash prevention on older devices), no

feature loss

[0.6.1] — 2026-08-08 — Shield hardening (P0/P1)

Fixed

  • REQ_KEY response no longer throttled (UDP key self-heal restored); audit hash-chain

parse fix; decrypt-failure frames no longer stored; disable cancels auto-relock; file-assembler sweep (10 min); Android biometric unlock fixed (FragmentActivity); audit persistence synchronized — 6 bugs, 4 regression tests

[0.6.0] — 2026-08-08 — Version unification

[0.5.0] — 2026-08-08 — Shield first release & version unification

Added (since 0.4.0)

  • ◇Mirtazapine Shield (first release): ARMED/LOCKED/UNLOCKED state machine,

biometric unlock; Android engine — Root / emulator / USB-debug / VPN change / background switch / accessibility abuse / monitoring apps; screen-capture protection (FLAG_SECURE); desktop engine — idle auto-lock (10 min); full-screen lock page; capability-boundary statement

  • Shield hardening: HMAC-signed settings (tamper → force-restore); disable requires

biometrics; 5-min unlock expiry; back-key blocking; threat severity grading; self-destruct protocol; chat-storage AES-GCM encryption (Keystore TEE / 0600 key); memory wipe while locked; Frida detection; audit persistence; clipboard protection

  • Server group E2E (per-member X25519 ciphertext, server sees only ciphertext)
  • Message search + forward + date dividers + unread badge + tray resident

(search removed in 0.4.0)

[0.4.0] — 2026-08-08 — Search removed, version unification

Changed

  • Message search removed (as requested); version strings unified to 0.4.0

[0.3.1] — 2026-08-08 — Server launcher app

Added

  • Standalone launcher app via jpackage (macOS .app / Windows / Linux app-image),

Gradle task launcherAppImage

[0.3.0] — 2026-08-07 — Version unification & tutorials

Added

  • Tutorial split into pure-English (TUTORIAL_EN.md) and pure-Chinese (TUTORIAL_ZH.md)

versions with entry page; server version unified; server dual-mode (CLI headless + --ui GUI with live status / members / history / logs)

[0.2.0] — 2026-08-06 — Private server

Added

  • Syna Server headless server (Win/macOS/Linux fat jar): TCP listening, password

auth, group relay, history persistence (history.jsonl), burn-after-reading server purge, member online/offline broadcast

  • Client join (IP:port + password, group-key encryption, history replay, disconnect

detection)

  • NAT traversal via frp / ngrok / Tailscale port mapping
  • Fixed serverId init-order NPE (identity lost on restart)

[0.1.0] — 2026-08-06 — Initial release

Added

  • Kotlin Multiplatform + Compose Multiplatform project (Android / Windows / macOS)
  • LAN peer discovery: UDP broadcast + multicast dual-channel, 3 s heartbeat,

15 s offline timeout, manual refresh

  • E2E encryption: X25519 key exchange + HKDF-SHA256 + AES-256-GCM; per-peer

session keys; REQ_KEY self-heal

  • 1:1 chat: conversation list (unread badges / timestamps / previews), bubbles,

✓✓ read receipts, connection status

  • P2P mesh group chat: create → invite → membership sync (JOIN/LEAVE), owner

dissolve, member leave

  • Burn after reading: 8 s display, destroyed on both sides (BURN_ACK + 60 s

fallback)

  • Temporary chat: auto-purge after TTL (1 h / 24 h / 7 d)
  • Connection modes: Auto / TCP / UDP / Host Hotspot; custom username; offline message

queue; typing indicator; message recall (2 min); quote reply & @mentions; image/file transfer (64 KB chunks, progress, ≤4 MB image preview); system notifications; dark/light theme; contact management (block / unblock); chat history persistence (JSONL, encrypted later); clear local history; proxy-TUN loopback normalization; Windows/macOS/Linux support


License

Syna is licensed under GPL-3.0-only. All dependencies are Apache-2.0 (compatible); no copyleft dependencies; all in-tree code is original. See LICENSE and SECURITY_AUDIT_REPORT.md.