diff options
| author | Danilo M. <danix@danix.xyz> | 2026-11-03 19:13:36 +0100 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-11-03 19:13:36 +0100 |
| commit | 89ec8dc13b03af9f7b74a82d187b9bee3c444925 (patch) | |
| tree | 68062dcacd8b36666be302e2abc3e441b3ad791e /app/src/main/java | |
| parent | cebdf8dd4720388d56d9af537fe81fd927e51779 (diff) | |
| download | HardenedPass-89ec8dc13b03af9f7b74a82d187b9bee3c444925.tar.gz HardenedPass-89ec8dc13b03af9f7b74a82d187b9bee3c444925.zip | |
fix(app): validate the proxy fully and keep its password out of properties
- A host with an empty port was saved, but ProxySelector treats port -1
as no proxy, so git silently connected directly. The port is now
required while a host is set.
- Patterns.WEB_URL accepted "http://proxy.example.org:3128/" as a host,
which then broke every HTTPS operation. The host must be a numeric
address or a plain domain name, without scheme, port or path.
- setDefaultProxy copied the proxy password into the process-wide
http.proxyPassword system property. The Authenticator already supplies
the credentials, so the properties are only cleared now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'app/src/main/java')
| -rw-r--r-- | app/src/main/java/app/passwordstore/ui/settings/ProxyViewModel.kt | 10 | ||||
| -rw-r--r-- | app/src/main/java/app/passwordstore/util/proxy/ProxyUtils.kt | 11 |
2 files changed, 10 insertions, 11 deletions
diff --git a/app/src/main/java/app/passwordstore/ui/settings/ProxyViewModel.kt b/app/src/main/java/app/passwordstore/ui/settings/ProxyViewModel.kt index ccd275a6..fb2bfe93 100644 --- a/app/src/main/java/app/passwordstore/ui/settings/ProxyViewModel.kt +++ b/app/src/main/java/app/passwordstore/ui/settings/ProxyViewModel.kt @@ -17,12 +17,13 @@ import app.passwordstore.util.settings.GitSettings import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject -/** A numeric address or a web host name, as the old proxy screen accepted. */ +/** A numeric address or a plain host name: no scheme, port or path, which the port field holds. */ fun isProxyHost(text: String): Boolean { val numeric = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) InetAddresses.isNumericAddress(text) else @Suppress("DEPRECATION") Patterns.IP_ADDRESS.matcher(text).matches() - return numeric || Patterns.WEB_URL.matcher(text).matches() + return numeric || + (!text.contains(':') && !text.contains('/') && Patterns.DOMAIN_NAME.matcher(text).matches()) } /** @@ -43,12 +44,13 @@ constructor(private val gitSettings: GitSettings, private val proxyUtils: ProxyU val hostError: Boolean get() = host.isNotBlank() && !isProxyHost(host.trim()) + /** Invalid, or empty while a host is set: a proxy without a port is not used at all. */ val portError: Boolean - get() = proxyPort(port) == null + get() = proxyPort(port).let { it == null || (it == -1 && host.isNotBlank()) } /** Stores the proxy and applies it at once; false, storing nothing, when a field is invalid. */ fun save(): Boolean { - if (hostError) return false + if (hostError || portError) return false val portValue = proxyPort(port) ?: return false gitSettings.proxyHost = host.trim().ifEmpty { null } gitSettings.proxyPort = portValue diff --git a/app/src/main/java/app/passwordstore/util/proxy/ProxyUtils.kt b/app/src/main/java/app/passwordstore/util/proxy/ProxyUtils.kt index 1b521141..6382e1ed 100644 --- a/app/src/main/java/app/passwordstore/util/proxy/ProxyUtils.kt +++ b/app/src/main/java/app/passwordstore/util/proxy/ProxyUtils.kt @@ -42,13 +42,10 @@ class ProxyUtils @Inject constructor(private val gitSettings: GitSettings) { ) val user = gitSettings.proxyUsername ?: "" val password = gitSettings.proxyPassword ?: "" - if (user.isEmpty() || password.isEmpty()) { - System.clearProperty(HTTP_PROXY_USER_PROPERTY) - System.clearProperty(HTTP_PROXY_PASSWORD_PROPERTY) - } else { - System.setProperty(HTTP_PROXY_USER_PROPERTY, user) - System.setProperty(HTTP_PROXY_PASSWORD_PROPERTY, password) - } + // The Authenticator below supplies the credentials; never copy the password into a + // process-wide system property. + System.clearProperty(HTTP_PROXY_USER_PROPERTY) + System.clearProperty(HTTP_PROXY_PASSWORD_PROPERTY) Authenticator.setDefault( object : Authenticator() { override fun getPasswordAuthentication(): PasswordAuthentication? { |
