Skip to content

FOSS build sends crash reports by default, contradicting the F-Droid listing's privacy claims #546

Description

@monkopedia-coder

Found during the 2026-08-07 audit pass (stream 3, data sensitivity).

The contradiction

The F-Droid listing shipped with v1.0.8 claims, in fastlane/metadata/android/en-US/full_description.txt:

Private by design — data never leaves the device except through a live, user-approved session.

and

Free and open source, with no analytics or tracking in the app.

The FOSS release build sends crash reports to a developer-controlled server automatically, with no consent prompt and no shipped opt-out. Both claims are false as written.

Evidence

app/src/main/java/com/rousecontext/app/RouseApplication.kt:134:

internal fun configureCrashReporting(
    crashReporter: CrashReporter = GlobalContext.get().get(),
    isDebugBuild: Boolean = BuildConfig.DEBUG
) {
    crashReporter.setCollectionEnabled(!isDebugBuild)
}

It takes no user preference. Collection is a pure function of BuildConfig.DEBUG, so every release build has it on, and onCreate (line 97) re-affirms it on every launch — a runtime toggle, if one existed, would be overwritten on next start.

app/src/foss/java/com/rousecontext/app/support/CrashReporterInitializer.kt configures ACRA with an HttpSenderConfigurationBuilder POSTing to the relay's /crash endpoint, derived from the same BuildConfig relay host as the tunnel. Its own KDoc states the destination and the gap:

Reports are POSTed as JSON to the relay's POST /crash endpoint, where they are sanitized, deduped, and turned into GitHub issues.

Release builds collect by default until a user opts out [...] so a future Settings opt-out can flip it at runtime.

The opt-out is described as future work. Grepping app/src/main/java/com/rousecontext/app/ui for a crash/telemetry/diagnostics toggle returns nothing relevant — there is no such control in Settings.

So the sequence on a stock F-Droid install is: user installs, app crashes once, a JSON report leaves the device to a server the user was told nothing about, and its contents may become a public GitHub issue. No live session is involved, and the user approved nothing.

Severity

The mitigations are real and worth stating: withLogcatArguments(emptyList()) deliberately excludes logcat to avoid other apps' data and PII, the relay sanitizes server-side, and the payload is intended to be stack trace plus app/OS version. This is not exfiltration of health data. putCustomData breadcrumbs are the part worth re-reviewing, since whatever callers put there rides along and can land in a public issue.

But severity here is not really about payload size. F-Droid users select that build specifically for the property the listing asserts, and the listing asserts it in the strongest available form ("never", "no analytics or tracking"). A shipped store listing making a false privacy claim is the defect, regardless of how benign the bytes are.

Also: no AntiFeatures declared

Neither fdroid/com.rousecontext.yml nor the submitted copy in fdroiddata!42096 declares an AntiFeatures: field. Whether default-on crash reporting requires one is a maintainer call and I am not asserting a policy violation — F-Droid's Tracking anti-feature is written around reporting activity without consent, and this is adjacent enough that it should be raised with linsui rather than decided unilaterally. Flagging it because the MR is open right now and this is cheaper to correct before inclusion than after.

Suggested fix, in priority order

  1. Make the listing true, or make the app match the listing. The fastest correct move is to default collection to off in the FOSS flavor until an opt-in exists. That makes both claims true immediately and costs only crash visibility on a build with few users so far.
  2. Ship the opt-out that CrashReporterInitializer's KDoc already promises, and have configureCrashReporting read it instead of BuildConfig.DEBUG alone. Note the current code would override a stored preference on every launch, so the toggle and this function must land together.
  3. Raise AntiFeatures with linsui on !42096.
  4. Re-review what putCustomData carries at each call site, given reports can become public issues.

Note on provenance

I converted this description from Markdown to HTML in #543 and did not change the prose, so the claim predates that change — but I had the file open and did not catch the contradiction, which is worth recording since the conversion was reviewed and merged.

Not covered elsewhere

#542 concerns ACRA reporting blocking the main thread (a threading defect) and #516 concerns ANR reporting via ApplicationExitInfo. Neither touches consent, disclosure, or the listing text.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingneeds-decisionRequires user input on direction, scope, or design

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions