Skip to content

Fix/phishing#58

Merged
muhammad7865 merged 4 commits intomainfrom
fix/phishing
Mar 11, 2026
Merged

Fix/phishing#58
muhammad7865 merged 4 commits intomainfrom
fix/phishing

Conversation

@muhammad7865
Copy link
Owner

@muhammad7865 muhammad7865 commented Mar 8, 2026

🛡️ Phishing Module — False Positive & Security Fixes

What & Why

The phishing scanner had critical gaps that allowed real attacks to slip through as safe, and shipped with zero code protection in release builds. This PR closes all of them.


Changes at a Glance

# Fix File(s) Severity
1 URL shortener expansion UrlExpander.kt · PhishingRepositoryImpl.kt 🔴 Critical
2 Homograph / Unicode detection HomographDetector.kt · PhishingRepositoryImpl.kt 🔴 Critical
3 Domain age via RDAP DomainAgeChecker.kt · PhishingRepositoryImpl.kt 🟠 High
4 Clipboard monitoring ClipboardMonitorService.kt · PhishingViewModel.kt · NotificationHelper.kt 🟠 High
5 ProGuard enabled build.gradle.kts · proguard-rules.pro 🔴 Critical
6 Safe DB migration CyberShieldDatabase.kt 🔴 Critical

Fix 1 — URL Shortener Expansion

Problem: bit.ly, t.co, tinyurl.com, goo.gl, ow.ly were hardcoded in the trusted whitelist. Any phishing URL hidden behind a shortener was instantly marked ✅ SAFE — ONNX and Safe Browsing never ran.

Fix: New UrlExpander.kt follows the redirect chain (HEAD → GET fallback, 6s timeout) for 21 known shorteners before any analysis. Shortener domains removed from whitelist. Expansion happens as the first step in checkUrl(), before Safe Browsing or ONNX. Scan history shows "expanded from bit.ly/xxx" so users know what was checked. Falls back silently on network failure — scan always continues.


Fix 2 — Homograph / Unicode Spoofing Detection

Problem: Domains like аpple.com (Cyrillic а) or pаypal.com are visually identical to their legitimate counterparts but resolve to completely different servers. The old code had no defence against this — these URLs passed right through.

Fix: New HomographDetector.kt runs before the whitelist, checking for:

  • Zero-width invisible characters (\u200B, \uFEFF, etc.) injected into the URL
  • Punycode labels (xn--) — already IDN-encoded Unicode domains
  • Non-ASCII characters remaining in the host
  • URISyntaxException from java.net.URI — itself a signal of illegal Unicode

Returns CRITICAL immediately with 0.99 confidence. No ONNX inference needed.


Fix 3 — Domain Age Check via RDAP

Problem: A brand-new secure-paypal-login-2024.com (registered yesterday) got the same ONNX threshold as paypal.com (registered 25 years ago). ~60% of phishing domains are under 30 days old at time of use — this signal was completely ignored.

Fix: New DomainAgeChecker.kt queries rdap.org (free, no API key, RFC 7483). Results cached in LRU for 24h. Domain age now directly lowers the ONNX decision threshold:

Domain age Threshold vs. default
< 7 days 0.20 60% lower
< 30 days 0.35 30% lower
Default 0.50

Never blocks — RDAP failures are swallowed silently.


Fix 4 — Clipboard Monitoring

Problem: The DB schema had a "CLIPBOARD" source field but no service populated it. Phishing URLs copy-pasted from WhatsApp, Telegram, or SMS were never scanned.

Fix: New ClipboardMonitorService.kt — foreground service (silent IMPORTANCE_MIN notification) registered with foregroundServiceType="specialUse". Two-path strategy required by Android 10+ privacy restriction:

  • App in foreground → read clipboard → scan → alert if phishing
  • App in background → OS blocks clipboard read → show "Tap to verify copied link" nudge notification → user taps → app opens → PhishingViewModel.checkFromClipboard() auto-scans

The real-time protection toggle in PhishingViewModel now actually starts/stops the service (previously it only updated UI state).


Fix 5 — ProGuard Enabled

Problem: isMinifyEnabled = false in release. The full un-obfuscated APK was shippable — anyone could decompile it with jadx and read the exact detection thresholds, whitelist patterns, and ONNX feature logic to build evasion.

Fix: isMinifyEnabled = true + isShrinkResources = true in release. proguard-rules.pro rewritten with keep rules for every library: Room entities, Retrofit/Gson models, Hilt, ONNX Runtime JNI, WorkManager, all Services/Receivers, and Kotlin metadata.


Fix 6 — Safe Database Migration

Problem: fallbackToDestructiveMigration() was active. Any future schema bump would silently delete all user scan history with no warning — unacceptable for a Play Store app.

Fix: Replaced with fallbackToDestructiveMigrationFrom(1, 2, 3, 4, 5, 6, 7). Dev databases (v1–7) can still be wiped. Version 8+ (production) will throw IllegalStateException if no migration is provided — forcing a proper Migration object before any schema change ships.


Files Changed

core/phishing/
  ├── UrlExpander.kt          ← NEW
  ├── HomographDetector.kt    ← NEW
  └── DomainAgeChecker.kt     ← NEW
service/
  └── ClipboardMonitorService.kt   ← NEW
data/repository/PhishingRepositoryImpl.kt   ← wired all 3 checks, removed shorteners from whitelist
data/local/CyberShieldDatabase.kt           ← safe migration
presentation/phishing/PhishingViewModel.kt  ← toggle wired to service, checkFromClipboard()
presentation/notification/NotificationHelper.kt  ← clipboard nudge notification
AndroidManifest.xml    ← service registered
build.gradle.kts       ← ProGuard on, Hilt plugin alias fix
proguard-rules.pro     ← full keep rules
test/
  ├── data/repository/PhishingRepositoryTest.kt      ← fixed mock type + missing stub
  └── presentation/phishing/PhishingViewModelTest.kt ← fixed constructor (added Context)

Fix 7 — CI / Test Compilation Fixes

Problem: The Android CI build (testDebugUnitTest) was failing due to three compile-time mismatches introduced during the phishing refactor.

Fixes:

Issue File Fix
Wrong mock type — PhishingOnnxScanner (private ctor) instead of PhishingScanner interface PhishingRepositoryTest.kt Changed to PhishingScanner
Missing networkMonitor.isCurrentlyConnected() mock in whitelist test PhishingRepositoryTest.kt Added every { networkMonitor.isCurrentlyConnected() } returns false
PhishingViewModel constructor gained Context param but test wasn't updated PhishingViewModelTest.kt Added Context mock, fixed constructor call
Root build.gradle.kts used id() instead of version catalog alias() for Hilt plugin build.gradle.kts Changed to alias(libs.plugins.hilt)

Out of Scope (Separate PRs)

  • Remote whitelist via Firebase Remote Config
  • User-managed custom whitelist UI
  • SMS monitoring (Phase 3)
  • Model hot-swapping from backend

muhammad7865 and others added 4 commits March 8, 2026 06:59
…etection, domain age & clipboard monitoring

- UrlExpander: follow redirect chain for 21 known shorteners (bit.ly, t.co,
  tinyurl, goo.gl, rb.gy, lnkd.in, etc.) before any analysis. Removed all
  shortener domains from the static whitelist — they were silently passing
  phishing-via-shortener as SAFE.

- HomographDetector: flag Punycode (xn--) labels, non-ASCII characters in
  domain, and zero-width invisible characters injected into URLs. Check runs
  before the whitelist so a spoofed domain can never slip through as trusted.

- DomainAgeChecker: query RDAP (free, no API key) for domain registration date.
  Lowers ONNX decision threshold to 0.20 for domains <7 days old and 0.35 for
  domains <30 days old. Results cached in-memory (LRU, 24h TTL).

- ClipboardMonitorService: foreground service that monitors clipboard changes
  and scans extracted URLs. Two-path strategy for Android 10+ background
  restriction. Real-time protection toggle now starts/stops the service.

- DB migration: replaced fallbackToDestructiveMigration() with
  fallbackToDestructiveMigrationFrom(1..7) — version 8+ never wipes user data.

- ProGuard: enabled isMinifyEnabled + isShrinkResources in release build.
  Added keep rules for Room, Retrofit/Gson, OkHttp, Hilt, ONNX Runtime,
  Compose, WorkManager, and all Android service/receiver components.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Merges fix/phishing worktree branch containing:
  - URL shortener expansion (bit.ly, t.co, tinyurl etc.)
  - Homograph / Unicode spoofing detection
  - Domain age check via RDAP (free, no API key)
  - Clipboard monitoring foreground service
  - ProGuard enabled for release builds
  - Safe DB migration strategy (no more destructive wipe on schema change)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@muhammad7865 muhammad7865 self-assigned this Mar 11, 2026
@muhammad7865 muhammad7865 merged commit 19ebd07 into main Mar 11, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant