fix(I4): warn on explicit ws:// non-onion relays (GHSA-8844-q5vh-9j8f)

network_security_config.xml permits cleartext globally (deliberate, for
local/onion relays). EditRelaysDialog auto-prefixes ws:// only for .onion /
private IPs but accepts user-typed explicit ws:// URLs, which then carry
kind-24133 NIP-46 traffic (E2E ciphertext + metadata over cleartext). Add
an in-app warning below the relay text field when the user explicitly
types ws:// for a non-onion / non-private-network host, so cleartext relays
are opt-in and informed. Update the network_security_config comment to
document the deliberate global scope and the in-app warning.
This commit is contained in:
greenart7c3
2026-08-14 07:07:19 -03:00
parent 96ee410767
commit 482d6bb2c8
3 changed files with 27 additions and 1 deletions
@@ -275,6 +275,26 @@ fun DefaultRelaysScreen(
},
)
// Defense-in-depth (GHSA-8844-q5vh-9j8f, I4): warn when the
// user explicitly types a ws:// URL for a non-onion /
// non-private-network relay, since NIP-46 traffic over
// cleartext exposes metadata + ciphertext to network
// observers. wss:// is the default; ws:// is auto-prefixed
// only for .onion / private IPs in onAddRelay.
val text = textFieldRelay.value.text
val showInsecureWarning = text.startsWith("ws://") &&
!text.endsWith(".onion") &&
!text.endsWith(".onion/") &&
!Amber.instance.isPrivateIp(text)
if (showInsecureWarning) {
Text(
text = stringResource(R.string.insecure_relay_warning),
color = MaterialTheme.colorScheme.error,
modifier = Modifier.padding(vertical = 8.dp),
fontSize = 12.sp,
)
}
LazyColumn(
Modifier
.weight(1f),
+1
View File
@@ -557,6 +557,7 @@
<string name="wss">wss://…</string>
<string name="require_unlocked_device">Require unlocked device for key access</string>
<string name="require_unlocked_device_description">When enabled, the Keystore key used to decrypt your stored account keys cannot be used while the device is locked. This prevents any code running in Amber\'s process from decrypting your keys while the screen is locked. Note: this disables background NIP-46 signing while the device is locked. Toggling this requires re-encrypting all stored keys.</string>
<string name="insecure_relay_warning">Insecure (cleartext, ws://) relay over the public internet exposes NIP-46 metadata and ciphertext to network observers. Prefer wss://, or use ws:// only for .onion / local-network relays.</string>
<string name="name_cannot_be_empty">"Name can't be empty "</string>
<string name="your_nsec_bunker_has_been_created">Your nsecbunker is ready!</string>
<string name="use_this_url_in_your_app">Use this url in your app:</string>
@@ -1,5 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Cleartext is intentionally allowed: users can connect to local/onion relays over ws:// -->
<!-- Cleartext is intentionally allowed (GHSA-8844-q5vh-9j8f, I4): users can
connect to local / onion relays over ws://. Global scope is required
because relay URLs are user-entered, not a fixed domain allowlist. The
EditRelaysDialog surfaces an in-app warning when the user explicitly
types a ws:// URL for a non-onion / non-private relay, so cleartext
NIP-46 traffic is opt-in and informed. -->
<network-security-config xmlns:tools="http://schemas.android.com/tools">
<base-config
cleartextTrafficPermitted="true"