Open-source audit & hardening · 2026-07-17

Link Clear — Audit & Hardening

app.linkclear · repo github.com/kisst/link-clearalready public (verified via gh) · 6 specialist sub-agents, read-only

SAFE
Public is fine to keep — hardening applied. Zero CRITICAL findings, no currently-exposed secrets. History clean, signing key uncompromised, license valid FOSS, no trackers / GMS / blobs. Both HIGH items are now closed: the wrapper SHA is pinned, and the transitive CVE scan ran (39 CVEs, all build/test tooling, zero shipped). Fixes committed to audit/pre-release-hardening, not pushed.
0
Critical
2→0
High (both fixed)
3/4
Medium fixed
0
CVEs shipped
6/6
F-Droid gates
6
Fix commits

Area verdicts

Secrets & historyCLEAN
No secret ever committed across 9 commits. Key not compromised. No rewrite, no rotation. Sole gitleaks hit is the public cert fingerprint.
F-Droid compliance6/6 PASS
License, no-GMS, no-trackers, no-blobs, fastlane metadata, reproducible (Path 1) all pass. No anti-features expected.
Android securityMINIMAL
No Device-Owner, no VPN — just INTERNET. 3 exported components, all guarded or benign. No history persisted.
Supply chain1 HIGH
All deps FOSS & GPL-compatible, nothing phones home. Missing wrapper SHA pin; transitive scan needs a JDK.
Release hygieneSOUND
R8 + resource shrink on, no backdoors, no tracked artifacts, env-driven signing. versionCode & allowBackup to address.
Docs & licensingDRAFTED
GPL-3.0-only, original icons. SECURITY.md, PRIVACY.md, build section & attribution drafted — uncommitted.

Findings & what was done

Fixedsupply-chain · B1 · HIGH
Gradle wrapper had no distribution checksum
Distribution was fetched over HTTPS but not hash-verified. Fixed: pinned distributionSha256Sum (verified against gradle.org); committed wrapper.jar also verified == upstream 8.14.4.
gradle/wrapper/gradle-wrapper.properties ✓ committed
Resolvedsupply-chain · B2 · HIGH
Transitive CVE tree — now scanned & clean of shipping CVEs
Scanned via the project's Nix toolchain + osv-scanner (324 artifacts). 39 CVEs, all in build/test tooling (AGP Unified Test Platform: netty/grpc/protobuf/commons-io; ktlint: logback). Zero reach the app's release classpath. A ktlint/detekt bump clears none (verified) — accepted as non-shipping; osv-scanner added to CI (warn-only).
0 vulnerable artifacts in releaseRuntimeClasspath ✓
Fixedandroid-security · M1 · MED
allowBackup denylist was fragile
Fixed: converted both backup configs to a fail-safe allowlist — nothing is backed up unless explicitly included (currently empty). Resources verified to compile.
app/src/main/res/xml/*backup*.xml ✓ committed
Fixedrelease-hygiene · M2 · MED
No versionCode increment strategy
Fixed: versionCode/versionName now derived from the git tag (monotonic for F-Droid). Both tag and dev-fallback paths verified to build.
app/build.gradle.kts ✓ committed
Fixedsupply-chain · M3 · MED
Two unused test dependencies
Fixed: removed androidx.test:core and espresso-core (kept the used runner's version ref). Config resolves clean.
gradle/libs.versions.toml ✓ committed
Opentooling · M4 · LOW
trufflehog verified-secrets pass not run
Low priority — gitleaks over full history was already clean. Run when convenient.
install trufflehog → git file://. --results=verified,unknown

Remediation status

Done Committed to audit/pre-release-hardening (not pushed)

  • B1 — pinned Gradle distributionSha256Sum (verified against gradle.org)
  • M1 — backup configs converted to a fail-safe allowlist
  • M2 — version derived from git tag (monotonic versionCode)
  • M3 — removed unused test deps
  • B2 / CVEs — transitive scan run; osv-scanner added to CI (warn-only)

Open Your decision — low priority

  • Install trufflehog; run the verified-secrets pass (gitleaks already clean)
  • Add keystore.properties, .env, *.p12 to .gitignore
  • Confirm SPDX intent — GPL-3.0-only recommended, consistently
  • Finalize 4 doc drafts; confirm GitHub private vuln reporting is enabled

Skipped Deliberately not done

  • ktlint/detekt bump "to clear CVEs" — verified it clears none; would be a false rationale
audit read-only no secret printed history untouched nothing pushed fixes on a branch, approved per-item Full detail in PRE_RELEASE_AUDIT.md