From 43962a6c06ffb4e933adbe94865e3278cd9913f5 Mon Sep 17 00:00:00 2001 From: Farnam Taheri Date: Mon, 11 May 2026 20:31:03 +0330 Subject: [PATCH 1/2] fix(android): harden app data and cleartext defaults Disable Android backup for sensitive VPN profile data and add explicit backup/data extraction exclusions for app databases, preferences, files, and external app storage. Deny cleartext traffic by default, remove file-scheme TOML imports from the exported import activity, and avoid showing SOCKS passwords in the Home telemetry card. --- android/app/src/main/AndroidManifest.xml | 5 +++-- .../com/masterdns/vpn/ui/home/HomeStatusCards.kt | 2 +- android/app/src/main/res/values/strings.xml | 1 + android/app/src/main/res/xml/backup_rules.xml | 7 +++++++ .../src/main/res/xml/data_extraction_rules.xml | 15 +++++++++++++++ .../src/main/res/xml/network_security_config.xml | 2 +- 6 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 android/app/src/main/res/xml/backup_rules.xml create mode 100644 android/app/src/main/res/xml/data_extraction_rules.xml diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 7149fbd..b2cc24b 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -19,7 +19,9 @@ - diff --git a/android/app/src/main/java/com/masterdns/vpn/ui/home/HomeStatusCards.kt b/android/app/src/main/java/com/masterdns/vpn/ui/home/HomeStatusCards.kt index 1548d7b..b66a7ab 100644 --- a/android/app/src/main/java/com/masterdns/vpn/ui/home/HomeStatusCards.kt +++ b/android/app/src/main/java/com/masterdns/vpn/ui/home/HomeStatusCards.kt @@ -157,7 +157,7 @@ fun MdvConnectionTelemetryCard( } if (socksPass.isNotBlank()) { Text( - text = stringResource(R.string.home_socks_password, socksPass), + text = stringResource(R.string.home_socks_password_hidden), style = MaterialTheme.typography.bodySmall, color = MdvColor.OnSurfaceVariant ) diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 64dc1e5..8064c1f 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -68,6 +68,7 @@ SOCKS5 authentication Username: %1$s Password: %1$s + Password: hidden PROFILE Connect Disconnect diff --git a/android/app/src/main/res/xml/backup_rules.xml b/android/app/src/main/res/xml/backup_rules.xml new file mode 100644 index 0000000..29eb0eb --- /dev/null +++ b/android/app/src/main/res/xml/backup_rules.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/android/app/src/main/res/xml/data_extraction_rules.xml b/android/app/src/main/res/xml/data_extraction_rules.xml new file mode 100644 index 0000000..ef6462f --- /dev/null +++ b/android/app/src/main/res/xml/data_extraction_rules.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/xml/network_security_config.xml b/android/app/src/main/res/xml/network_security_config.xml index d7b4192..683208f 100644 --- a/android/app/src/main/res/xml/network_security_config.xml +++ b/android/app/src/main/res/xml/network_security_config.xml @@ -1,6 +1,6 @@ - + From 2aa9421f34d0b3aa76512e6cbc1abf44d7a8da77 Mon Sep 17 00:00:00 2001 From: Farnam Taheri Date: Mon, 11 May 2026 21:28:25 +0330 Subject: [PATCH 2/2] fix(android): redact sensitive log content Mask common secret assignments and app-local file paths before Android/core log lines enter the UI and shareable log flows. Resolver IPs and scan counters remain visible so telemetry parsing continues to work. --- .../java/com/masterdns/vpn/util/VpnManager.kt | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/android/app/src/main/java/com/masterdns/vpn/util/VpnManager.kt b/android/app/src/main/java/com/masterdns/vpn/util/VpnManager.kt index 2b7e116..c1861b9 100644 --- a/android/app/src/main/java/com/masterdns/vpn/util/VpnManager.kt +++ b/android/app/src/main/java/com/masterdns/vpn/util/VpnManager.kt @@ -78,6 +78,13 @@ object VpnManager { private var trafficMonitorJob: Job? = null private const val MAX_LOG_LINES = 500 + private const val REDACTED_VALUE = "" + private val SENSITIVE_ASSIGNMENT_REGEX = Regex( + "(?i)\\b(ENCRYPTION_KEY|SOCKS5_PASS|SOCKS5_USER|PASSWORD|PASS|TOKEN|SECRET)\\b\\s*[:=]\\s*(\"[^\"]*\"|'[^']*'|[^\\s,;]+)" + ) + private val ANDROID_APP_PATH_REGEX = Regex( + "(?:/data/(?:user|data)/\\d*/?[^\\s,;]+|/data/data/[^\\s,;]+|[A-Za-z]:\\\\Users\\\\[^\\s,;]+)" + ) fun updateState(newState: VpnState) { _state.value = newState @@ -108,7 +115,7 @@ object VpnManager { } private fun appendLogInternal(line: String, source: LogSource) { - val normalizedLine = normalizeLogTimestampToLocal(line) + val normalizedLine = redactSensitiveLogContent(normalizeLogTimestampToLocal(line)) val upper = normalizedLine.uppercase() val isError = upper.contains("[ERROR]") || upper.contains(" ERROR ") val isWarn = upper.contains("[WARN]") || upper.contains(" WARNING ") || upper.contains(" WARN ") @@ -127,6 +134,14 @@ object VpnManager { parseScanLine(normalizedLine) } + private fun redactSensitiveLogContent(line: String): String { + return line + .replace(SENSITIVE_ASSIGNMENT_REGEX) { match -> + "${match.groupValues[1]}=$REDACTED_VALUE" + } + .replace(ANDROID_APP_PATH_REGEX, "") + } + fun clearLogs() { _logEntries.value = emptyList() _logs.value = emptyList()