#11894·NemoClaw

[Linux][Agent&Skills] channels login accepts an over-length or metacharacter-bearing WhatsApp account identifier and starts pairing instead of rejecting it

Author: wangericnvCreated Sep 16, 2026Updated Sep 18, 2026

Description

openclaw channels login --channel whatsapp --account {id} performs no validation of the account identifier. An identifier of 129 characters and an identifier containing shell metacharacters are both accepted, and the command goes straight into the QR pairing flow instead of rejecting them.

The flag is not inert - it changes behaviour. On a sandbox whose WhatsApp channel is already paired, channels login with no --account exits 0 immediately, while the same command with any --account value starts a fresh pairing flow and renders QR codes. So the value is consumed as an account selector, it is simply never checked.

No length limit or character set is stated anywhere in channels login --help, which documents the flag only as "Account id (accountId)".

One thing that does hold: the metacharacters are not executed. An identifier of test";injection produced no shell execution of the injected text, so this is an input-validation gap rather than a command-injection defect.

Platform scope: Reproduced on an x86_64 Ubuntu 24.04 instance; the check would live in the channel login path and is not expected to be hardware specific. Other platforms not tested this pass. Regression: Unknown - earlier builds not tested this pass. OpenShell issue: No - the command runs inside the sandbox through the OpenClaw CLI; the gateway and sandbox are healthy throughout and the same sandbox's paired channel keeps working.

Environment

Device:        x86_64 cloud instance
OS:            Ubuntu 24.04.4 LTS
Architecture:  x86_64
Kernel:        6.11.0-1016-nvidia
Node.js:       v22.23.2
npm:           10.9.8
Docker:        Docker version 29.7.2, build a7dcaa6
OpenShell CLI: openshell 0.0.116
NemoClaw:      nemoclaw v0.0.125
OpenClaw:      2026.7.1 (2d2ddc4)

Steps to Reproduce

Start from a sandbox whose WhatsApp channel is already paired, so the "already linked"
baseline is available for comparison.

1. Confirm the channel is paired:
   nemoclaw {sandbox} channels status --channel whatsapp

2. Baseline - no account flag. The command should recognise the existing link:
   nemoclaw {sandbox} exec -- sh -lc 'openclaw channels login --channel whatsapp'

3. Over-length identifier, 129 characters:
   nemoclaw {sandbox} exec -- sh -lc 'openclaw channels login --channel whatsapp --account aaaa...'
   (129 'a' characters)

4. Identifier containing shell metacharacters:
   nemoclaw {sandbox} exec -- sh -lc 'openclaw channels login --channel whatsapp --account '\''test";injection'\'''

5. Short bogus identifier, as a control for whether the flag is read at all:
   nemoclaw {sandbox} exec -- sh -lc 'openclaw channels login --channel whatsapp --account zzz-not-a-real-account'

6. Confirm the valid account is unaffected:
   nemoclaw {sandbox} channels list
   nemoclaw {sandbox} channels status --channel whatsapp

Expected Result

Steps 3 and 4 exit non-zero before any pairing flow begins, and say why: that the identifier exceeds the supported length, and that it contains unsupported characters. The supported length and character set are stated in channels login --help.

Actual Result

  invocation                                  pairing flow started   rejection message
  no --account                                no                     n/a, exits 0
  --account zzz-not-a-real-account            yes                    none
  --account {129 characters}                  yes                    none
  --account test";injection                   yes                    none

Every run with an --account value printed the same opening lines and then began
rendering QR codes:

  [whatsapp] Pairing via the in-sandbox gateway (loopback).
  [whatsapp] On your phone, open WhatsApp, then Linked devices, then Link a device,
  and scan the QR below.
  Open the WhatsApp app, go to Linked Devices, then scan this QR:

No output from any run matched a length, character-set, or format rejection.

The runs with an --account value did not return on their own; they were stopped by the
test harness after the pairing flow had clearly started. The baseline with no --account
returned immediately with exit 0, which is what shows the flag is read and acted upon
rather than ignored.

`channels login --help` documents the flag with no constraint:

  --account {id}       Account id (accountId)

Step 6: the valid paired account is unaffected. `channels list` still shows whatsapp,
and after these attempts the channel continued to deliver: three inbound direct
messages were received and the agent's reply was sent in 342 ms, with the channel
status reporting Verdict: healthy.

Logs

Discriminating run, three invocations back to back on one sandbox:

  no --account        exit 0    pairing flow started: no
  bogus short account timed out pairing flow started: yes   rejection lines: 0
  129-character       timed out pairing flow started: yes   rejection lines: 0

Channel health after the attempts:

  [ok] Pairing / session: paired
  [ok] Bridge process: bridge process running
  [ok] Noise WebSocket: connection state: open
  [ok] Inbound delivery: last inbound at {timestamp}
  Verdict: healthy

Related / not duplicate of

  • #10383 — Google Chat channel setup rejects a valid service-account credential for containing line breaks. That is over-strict validation rejecting a valid input on a different channel; this is absent validation accepting invalid input on WhatsApp.