Skip to content

Ghost FTP 0.95.4

Choose a tag to compare

@github-actions github-actions released this 12 Oct 21:49
3bc23f5

Ghost FTP 0.95.4 — Android SAF download integrity security candidate (NOT PUBLISHED)

Latest verified public GitHub release: v0.95.3 (12 October 2026), immutable commit 1e79375e97ab2efbaa4ebaa2c91302908074d370. This candidate changes real source and does not rewrite any tag.

Security change: Android saved-document readback

  • A successful network download is staged in app-private cache and checked against a provider's optional S3 SHA-256 header, plus the actual HTTP content length when known.
  • After closing the SAF output stream, the app now reopens the actual destination document through Android ContentResolver, streams it without a second full memory copy, and requires identical byte count and constant-time SHA-256 digest versus the verified staging file.
  • A provider that silently truncates, modifies, appends bytes, or cannot read back the saved file fails closed rather than showing a false success. Existing failure cleanup attempts to delete the newly created SAF document and warns if the provider refuses.
  • The document picker explicitly requests read and write URI grants for this check. Signed cloud URLs remain ephemeral and no secret is added to saved state or diagnostics.
  • Added isolated JVM regressions for exact/zero-length documents, truncated/oversized outputs, same-length corruption, invalid checksums, cancellation and providers returning endless zero-byte reads. Non-progressing streams fail closed after bounded retries.
  • Windows/Linux Tauri IPC: Upgrade the Rust Tauri core from vulnerable 2.11.4 to patched 2.11.6 (GHSA-w28w-mhc8-qvjv) and regenerate the exact Cargo dependency lock graph.
  • Updater anti-rollback: Upgrade Rust tauri-plugin-updater from 2.10.1 to 2.12.0 and npm frontend updater to locked 2.12.0. Explicitly set allowDowngrades: false and requireSignedVersion: true, preventing a tampered unsigned update manifest from presenting an old signed package as a newer release. Upgrade the signing Tauri CLI to locked 2.12.2 so tauri build embeds its exact version in the minisign signed trusted comment. Rust and JavaScript updater versions are intentionally on the same 2.12.x train to satisfy Tauri's actual build-time package compatibility checks. The existing signing key/asset publishing workflow remains unchanged; independently verify its signed updater bundles before public rollout.
  • Regression safety: New GitHub Quality gate verifies patched Rust/npm versions and regenerated lockfiles; tests fail if downgrades are enabled, signed-version binding is disabled, or the signing CLI is older than 2.12. Temporary dependency lock-generation workflow was removed after generating the lockfiles in CI.
  • Android and macOS SSRF defense in depth: Both public-DNS/peer filters reject RFC 9637's non-global documentation prefix 3fff::/20, IANA benchmarking 2001:2::/48 and deprecated ORCHID 2001:10::/28. Android also revalidates ASCII hostname syntax within OkHttp's actual DNS hook, independent of initial signed-link parsing. Added platform unit tests. Controlled DNS/proxy/VPN and real-provider labs remain unverified under #126.

Limitations and outstanding security acceptance

Readback cannot guarantee durable physical storage against a provider that lies on both reads and writes, nor can it supply atomic replacement for SAF implementations lacking transactions. Real provider tests on Android 8–15, permission revocation, low-storage/disk-full, rotation, app death and cancellation remain not completed and required under reopened #127.

Reopened #126: controlled DNS/proxy/VPN/rebinding lab plus real S3/GCS/Azure compatible provider results are required despite connection-bound IP policy. Reopened #128: Android/macOS OAuth account login, PKCE, secure refresh token storage and actual browsing remain unimplemented. This change does not implement them.

Windows/Linux desktop behavior additionally changes through the security-patched Tauri runtime/updater and signed-version enforcement; macOS functional transfer behavior is otherwise unchanged except for tightened public IPv6 routing policy. All six exact-head workflows, packaging and physical-device acceptance must be verified before merging or publishing. Do not advertise full 75-screen pixel parity or stable FINAL.