This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user