block / block/buzz

Mobile: QR pairing fails at credential import for private/VPN-only relays (relay URL must be HTTPS + public host)

Open
#4,198 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
32.7k
Forks
4.3k
Avg merge
1d 13h
Merged PRs (30d)
253

Description

## Summary

Buzz Desktop fully supports private, VPN-only relays, and the NIP-AB pairing flow (including the `buzz-pair-relay` sidecar from #467/#470/#1799) works end-to-end against them. But the mobile app rejects the community credentials at the final import step, making mobile unusable for private-relay deployments.

## Environment

- Self-hosted relay (docker compose, image `ghcr.io/block/buzz:sha-3e48f1b`), NIP-43 auth enabled
- Relay reachable only inside a WireGuard tunnel: `ws://10.88.0.1:3000`
- `buzz-pair-relay` sidecar deployed and advertised via NIP-11 `pairing_relay_url`
- Mobile: current release build (iOS)

## What happens

1. Desktop shows QR → phone (on the VPN) connects to the pairing sidecar
2. NIP-AB handshake completes, SAS codes match and confirm
3. Credential payload transfer starts, then mobile errors:
`Failed to import credentials: FormatException: Relay URL must use HTTPS`

## Why

`mobile/lib/features/pairing/pairing_provider.dart` → `_validateRelayUrl()` requires `https` scheme in release builds, and `_isPrivateHost()` rejects RFC1918 addresses. A VPN-only relay URL like `ws://10.88.0.1:3000` fails both, with no way to override. `mobile/lib/shared/relay/relay_validation.dart` enforces the same policy for invites (`wss` + no non-public addresses).

The SSRF motivation for these checks makes sense for untrusted invite links, but at the end of a NIP-AB pairing the user has just cryptographically verified the source device via SAS — the relay URL comes from their own desktop, not an untrusted third party.

## Ask

A supported path for private/VPN-only relays on mobile. Possible shapes:

- Treat SAS-verified pairing payloads as trusted enough to accept `ws://` + private-range relay URLs (perhaps behind an explicit "this is a private relay — connect anyway?" confirmation), or
- A user-visible setting/build flag to allow private relay origins, or
- Documented guidance if the intended answer is "front the relay with WSS + public DNS" — including how an existing community keyed by a `ws://` URL is supposed to migrate, since docs state the relay URL keys the community and must never change.

Happy to test a patch against our deployment.

Contributor guide

Open the contributing guide

Research direction

Start in mobile/lib/features/pairing/pairing_provider.dart at _validateRelayUrl(), then compare its release-build checks with mobile/lib/shared/relay/relay_validation.dart. Reproduce the final credential import using the documented ws://10.88.0.1:3000 VPN relay and review how SAS verification relates to the SSRF protections. Done means a supported private-relay path is defined and works, or the required public WSS migration guidance is documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart, flutter, ios
Domain
mobile, networking, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.