[Linux][Agent&Skills] channels login accepts an over-length or metacharacter-bearing WhatsApp account identifier and starts pairing instead of rejecting it
- Dominant language
- TypeScript
- Stars
- 22.5k
- Forks
- 3.1k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 715
Description
## 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
```text
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
```bash
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
```text
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
```text
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.
Contributor guide
Research direction
Start at the `openclaw channels login --channel whatsapp --account {id}` CLI entry point and trace how the account value reaches the pairing flow and help text. Add validation and regression coverage for over-length and unsupported-character identifiers, then verify that invalid values are rejected before QR pairing while an existing valid account remains unaffected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 70/100