92 lines
6.4 KiB
Markdown
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.
|