security-assessment-2026-09-01-plan.md

9.1 KB · raw

rendered · source

Implementation Plan: 2026-09-01 Security Assessment Remediation

Overview

Resolve every open finding in docs/peach-android-independent-security-assessment-2026-09-01.pdf against the current v2.14.89 tree. Work is ordered by release risk, delivered as small Koh saves, and kept separate from the deferred PIN hardware-validation queue.

Architecture Decisions

Task List

Phase 1: Release-root blockers

Checkpoint: Release blockers

Phase 2: Integrity and privacy boundaries

Checkpoint: Integrity and privacy

Phase 3: Supply-chain and helper hardening

Checkpoint: Complete

Finding Resolution Details

PB-26-025 - Signing credentials

Acceptance criteria: no signing password or keystore path is read from local.properties; local-only configuration is ignored; missing protected inputs cannot silently produce a publishable release; a sanitized history/workspace search is recorded. Rotation, revocation, backup/CI review, and old-signer disposition are owner actions and must not be falsely marked complete from source changes alone.

Verification: configuration tests or Gradle task checks cover missing/present injection; koh diff contains no secret value; a fresh-workspace release build path is documented and exercised where credentials are available.

Likely files: .gitignore or Koh ignore configuration, app/build.gradle, release documentation.

PB-26-026 - Release shrinking

Acceptance criteria: release enables minifyEnabled and shrinkResources; narrow project keep rules exist; security-sensitive reflection/serialization paths continue working.

Verification: unit, lint, release, APK inspection, and device smoke tests for unlock, autofill, passkeys, updates, crypto/import, and sync/pairing.

Likely files: app/build.gradle, app/proguard-rules.pro, focused tests/documentation.

PB-26-027 - External URL allowlist

Acceptance criteria: bare valid hosts and HTTPS normalize safely; HTTP, intent:, file:, custom schemes, malformed authorities, credentials, control characters, and encoded separator attacks do not reach ACTION_VIEW.

Verification: focused pure unit tests first, then compile and a manual open-link smoke test.

Likely files: AdditionalUrlsDetail.kt, a focused JVM test.

PB-26-028 - Signed update metadata

Acceptance criteria: a versioned signature covers the exact trusted manifest bytes; verification uses a pinned public key before parsing URLs/checksums/notes; unknown keys, invalid signatures, stale metadata, and rollback fail closed.

Verification: deterministic signature vectors plus forged HTTPS, key transition, alternate URL, stale, and rollback tests.

Dependencies: release-side offline signing key and manifest signing step must be available before completion. The current local architecture spans three repositories: Koh publishes the artifacts, Kepr persists and serves the release record, and Peach verifies it. Koh's updater already defines a per-platform Ed25519 envelope shape, but the build/offer path does not produce those signatures and Kepr's generic endpoint does not persist or emit them. Reuse that shape only after defining one canonical byte payload and a production key-custody boundary. The public Kepr service must not hold the offline private key.

Likely files: UpdateRepository.kt, manifest model/tests, Kepr build/release scripts and documentation.

PB-26-029 - Debug seed isolation

Acceptance criteria: predictable usernames, passwords, and TOTP seeds leave production source; debug QA data is generated at runtime or isolated under debug/test sources; release artifact string/symbol inspection is clean.

Verification: debug seed behavior test plus release APK scan.

Likely files: VaultListViewModel.kt, debug source-set helper, focused tests.

PB-26-030 - Favicon consent

Acceptance criteria: enabling site icons requires explicit copy naming DuckDuckGo and explaining one request per distinct vault domain; declining or disabling causes no network requests; prior opt-ins are re-consented after the copy change.

Verification: settings-state tests, UI test where practical, and network-capture/fake-client proof of zero opt-out requests.

Likely files: settings model/UI, VaultListScreen.kt, favicon tests and privacy documentation.

PB-26-031 - Release logging

Acceptance criteria: production sync/pairing logs contain only allowlisted opaque event names and redacted error classes; payloads, peer identifiers, protocol material, raw exception messages, and stack traces are excluded.

Verification: logger unit tests and a release log capture under malformed inputs.

Likely files: sync logging helper and the three reported sync/adoption call sites.

PB-26-032 - Rust provenance

Acceptance criteria: Rust channel/version and target inputs are pinned; Cargo uses the lockfile; produced native artifacts have recorded source/toolchain/target hashes or equivalent reproducible provenance.

Verification: pinned-toolchain build and provenance output comparison.

Likely files: rust-toolchain.toml, root build.gradle, native build/release documentation.

PB-26-033 - Favicon cache containment

Acceptance criteria: helper accepts only canonical validated DNS hosts; every hit/miss cache path remains a direct child of the favicon cache directory; invalid caller material cannot create, read, or write another path.

Verification: traversal, separator, Unicode/control, malformed-host, and valid-IDN/domain unit tests.

Likely files: Favicons.kt, focused tests.

Risks and Mitigations

Risk Impact Mitigation
Signing credentials may already exist outside this workspace Source cleanup cannot revoke compromise Keep release blocked until the owner completes rotation/exposure review
R8 removes reflected or JNI-reached code Runtime-only regression Start with narrow rules, inspect mapping/usage, and run device smoke gates
Signed metadata requires release-channel coordination Client-only change could block all updates Land signer tooling and client verification as one coordinated, rollback-tested unit
Re-consent reduces favicon adoption Expected privacy tradeoff Use concise, explicit copy and preserve initials fallback
Log reduction hurts diagnostics Production failures become harder to investigate Retain opaque event IDs and detailed debug-only logs

Open Questions