Files
zemion db873063f8
Verify source and build Android / android (push) Canceled after 0s
initial commit v 0.2.0
2026-09-24 22:49:27 +02:00

92 lines
6.4 KiB
Markdown

# Security and privacy model
This is an unaudited MVP source release. “No network permission” does not mean “no possible
vulnerability,” and passing the included tests does not prove safety for arbitrary hostile files.
## Trust boundaries
An external app/provider controls document bytes, MIME type, metadata and timing. Name/MIME hints
are not treated as proof of format. The app accepts external `content://` URIs, not arbitrary
filesystem paths or HTTP URLs. Its own share-provider URIs are rejected as incoming documents to
reduce confused-deputy access to private cached data.
Providers and the Android platform are still dependencies. A chosen cloud provider can fetch bytes
using its own network permissions. Provider reads/queries may block; a coroutine cancellation is
not a universal hard timeout for a malfunctioning provider.
## Implemented controls
- Main manifest requests no INTERNET, broad storage, contacts or account permissions.
- Originals are read-only; bounded private copies provide stable/seekable inputs.
- Known macro-enabled files and VBA packages are rejected; no formula/macro/script engine exists.
- HTML, XML and SVG can be shown as source, never executed in a WebView.
- The document core does not fetch embedded external resources, relationships, fonts, images or URLs.
User-chosen provider files and opt-in provider thumbnails can involve the provider's own networking.
- ZIP entries are never extracted to filesystem paths. Traversal/absolute/ambiguous paths and
duplicate names are rejected; inflated bytes, entry count, ratio, cumulative expansion and CRC
are checked when applicable. Listing does not inflate large entries.
- XML DTD, custom/general entities and other declarations are disabled. No network/entity resolver
exists. Nesting/node/attribute/output limits reduce denial-of-service opportunities.
- Repeated ODF rows/cells and OOXML shared strings have output budgets.
- PDF input/output are confined to an isolated Android service using file descriptors. The host
accepts only dimension-checked raw ARGB output, not attacker-provided executable objects/HTML.
- The nonexported share FileProvider exposes only `cache/shared/` and `cache/picked/`, not the app root,
sessions, recents or saved folder grants. Outgoing intents grant individual copies read-only access.
- Picker MIME filters are checked before selection and rechecked against fresh metadata at confirmation.
Actual streamed byte counts enforce per-file and aggregate budgets regardless of declared sizes.
- LOCAL_ONLY picker requests delegate to Android with the same constraints rather than query arbitrary
saved provider folders. No URI supplied in incoming picker extras is automatically selected/read.
- Exported activity intents are sanitized before ViewModel creation to prevent caller-supplied saved-state
keys such as sourceUri/browser.selection from seeding previews or selections using existing grants.
- Document-history grant cleanup is separate from bookmark tree-grant cleanup. Originals are never deleted.
- Provider query jobs have a bounded worker pool, CancellationSignal, and an awaiting timeout. Listings,
labels, thumbnails, selections and copied bytes have explicit bounds. No recursive scan occurs.
- Active preview snapshots are tracked across concurrent viewer/picker activities; one viewer's startup
no longer unconditionally deletes another viewer's live input file.
- Backup and device-transfer exclusions are configured. No content/URI logging or analytics calls
are present in application source.
## Explicit remaining work
Native image decoding is not separately sandboxed. The common XML/Office code is a limited custom
parser, not independently audited. Complete namespace/schema semantics are not checked. Unicode
and malformed-package fuzzing needs broader coverage. Rich Office rendering will substantially
increase the native attack surface and requires a fresh review.
Android compilation, IPC, lifecycle, provider behaviour, device-memory pressure, process death,
export races, accessibility and actual permission/backup behaviour have not been runtime-tested
here. The PDF timeout handles the awaiting client; it is not a proof of immediate worker termination
on every device or cancellation path. Run the acceptance checks before ordinary distribution.
There is no application-level encryption, master password or secure-window mode. File names/URIs
in recents can be sensitive. Displayed content can appear in screenshots/app-switcher previews.
Copying selected text and explicit shares pass content to platform/recipient surfaces. Cache cleanup
is not cryptographic erasure. Uninstall behaviour, device backups and rooted-device access are not
security guarantees provided by this project.
Dependencies are directly version-pinned but no resolved dependency verification manifest, SBOM or
transitive lockfile is included. Generate and review these after a real build. Release signing keys
must be created and controlled by the project owner, not bundled into this repository.
## Before sensitive production use
Require successful Android tests on at least the oldest supported API and a current device, a
reviewed hostile-document corpus, memory/timeout tests, IPC failure tests, dependency scanning,
licence review and an external security review appropriate to the intended users.
## Browser-specific residual risks
FileProvider/intent grants, actual Android SavedStateHandle behaviour, external caller access, and
provider query cancellation have not been device-verified. Same-UID fixture tests are not proof of
cross-UID grant isolation. Copied content can change between metadata retrieval and streaming; the
copy is bounded, not a transactional snapshot of an arbitrary external provider. MIME is metadata,
not proof of safe bytes. Native thumbnail/image decoding needs independent hostile-input review.
Temporary GET_CONTENT copies are for prompt import, not permanent links. Explicit cache clearing,
Android cache eviction or expiry can invalidate them. A receiver cannot write the source document.
No immutable/versioned cloud snapshot semantics are claimed. Shared MIME metadata is private,
bounded and cleared alongside snapshots. Persistent browser bookmarks contain sensitive names/URIs.
A debug-only DocumentsProvider supplies synthetic fixture files for tests. It is protected by the
system document-provider permission and is absent from release builds; it never serves user storage.