Skip to content

[Bug]: iOS app silently rejects QR setup codes with LAN ws:// URLs #98297

Description

@joelnishanth

Summary

The iOS app's GatewayConnectDeepLink.fromSetupCode method silently rejects QR setup codes generated by openclaw qr when the gateway is bound to LAN (gateway.bind=lan). The method uses LoopbackHost.isLoopbackHost which only allows 127.0.0.1/::1, but LAN mode generates ws://192.168.x.x:18789 URLs with RFC 1918 private IPs.

Root cause

In apps/shared/OpenClawKit/Sources/OpenClawKit/DeepLinks.swift, line 40:

if !tls, !LoopbackHost.isLoopbackHost(hostname) {
    return nil
}

This check was introduced in commit ebae6f918e1 (PR #21970) as a security hardening measure. However, it is too strict — it blocks the primary use case for LAN QR pairing.

The same file's sibling utility LoopbackHost.isLocalNetworkHost (in LoopbackHost.swift) already handles RFC 1918 private IPs, .local hostnames, Tailscale .ts.net addresses, and bare hostnames. This method exists but is not used by fromSetupCode or the deep link parser (line 135).

The same over-restriction exists in DeepLinkParser.parse at line 135 for the openclaw://gateway deep link path.

Steps to reproduce

  1. Configure gateway with gateway.bind=lan in openclaw.json
  2. Start gateway: openclaw gateway
  3. Generate QR: openclaw qr
  4. QR encodes payload like: {"url":"ws://192.168.1.249:18789","token":"..."}
  5. Open iOS app onboarding → Scan QR
  6. Nothing happensfromSetupCode returns nil, scan silently fails

Expected behavior

The iOS app should accept ws:// setup codes pointing to local network addresses (RFC 1918, .local, bare hostnames, Tailscale IPs), since these represent the primary LAN pairing workflow.

Suggested fix

Change isLoopbackHost to isLocalNetworkHost on both lines:

DeepLinks.swift:40 (fromSetupCode):

if !tls, !LoopbackHost.isLocalNetworkHost(hostname) {
    return nil
}

DeepLinks.swift:135 (DeepLinkParser.parse, gateway case):

if !tls, !LoopbackHost.isLocalNetworkHost(hostParam) {
    return nil
}

This preserves the security intent (reject ws:// to public internet hosts) while allowing the documented LAN pairing flow.

Environment

  • OpenClaw: main (latest)
  • iOS app: built from source
  • Gateway bind: lan
  • Device: iPhone on same LAN as gateway host

Related issues

Joel Nishanth · offlyn.AI

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.maturity:stableIssue affects a taxonomy feature currently scored M4/M5.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions