#13090: fix: Device-pair extension leaks gateway credentials in chat messages
extensions: device-pair
stale
Cluster:
Device Pairing and Gateway Fixes
## Fix Summary
The device-pair extension's `/pair` command sends the gateway authentication credential (token or password) as a base64url-encoded chat message. Anyone with read access to the chat (group members, message backups, forwarded messages, or platform admins) can trivially decode the setup code and extract the full gateway credential, granting unauthorized gateway access with self-declared admin scopes.
## Issue Linkage
Fixes #13088
## Security Snapshot
- CVSS v3.1: 9.0 (Critical)
- CVSS v4.0: 9.4 (Critical)
## Implementation Details
### Files Changed
- `extensions/device-pair/index.ts` (+9/-56)
### Technical Analysis
The `/pair` command in `extensions/device-pair/index.ts` resolves the gateway auth credential (token or password) from configuration or environment variables via `resolveAuth()`, then constructs a `SetupPayload` containing the URL and credential. This payload is JSON-serialized and base64url-encoded by `encodeSetupCode()`, then sent as a plain-text chat message to the channel where `/pair` was invoked.
Base64 encoding is a reversible encoding, not encryption. Any observer who can read the chat message can decode it with a single `atob()` call or `echo <code> | base64 -d` to extract the raw gateway token or password.
The gateway's shared-auth path (token/password) allows connections to self-declare arbitrary scopes including `operator.admin` (see `message-handler.ts:359-367`). Scope enforcement only applies to device-paired connections, not shared-auth ones. This means the leaked credential grants full unrestricted administrative access to the gateway.
## Validation Evidence
- Command: `pnpm build && pnpm check && pnpm test`
- Status: passed
## Risk and Compatibility
non-breaking; no known regression impact
## AI-Assisted Disclosure
- AI-assisted: yes
- Model: GPT-5.3-Codex
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This change removes gateway authentication credentials (token/password) from the `/pair` setup payload in `extensions/device-pair/index.ts`, so the generated base64url setup code no longer contains secrets that can be trivially decoded from chat history. The command output text/instructions are updated accordingly to require entering the gateway credential manually in the iOS app, while keeping the existing URL resolution behavior and Telegram “split send” flow.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk.
- The change is narrowly scoped to removing credentials from the pairing payload and adjusting user-facing instructions. I did not find any remaining code paths in this extension that include token/password in the encoded setup message, and the compilation surface area is small (single file, type changes align with usage).
- extensions/device-pair/index.ts
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#16310: fix(ws-connection): skip device pairing when client authenticates w...
by nawinsharma · 2026-02-14
80.6%
#22712: fix(gateway): auto-approve all device pairing for localhost connect...
by NewdlDewdl · 2026-02-21
79.1%
#23503: fix: preserve pairing state on device token mismatch + migrate lega...
by dorukardahan · 2026-02-22
79.0%
#21664: fix(gateway): require re-pairing for legacy devices that lack scope...
by AI-Reviewer-QS · 2026-02-20
78.1%
#22280: fix(gateway): silently auto-approve local paired-device scope upgrades
by abhishekp76 · 2026-02-21
77.7%
#6846: fix: bridge node.pair.* tools to device pairing store
by cortexuvula · 2026-02-02
77.6%
#17425: fix(gateway): auto-approve scope/role upgrades for already-paired d...
by sauerdaniel · 2026-02-15
77.3%
#20422: Fix/tailscale device pairing
by slagyr · 2026-02-18
77.3%
#21666: fix(gateway): restrict auto-paired device scopes to safe defaults
by AI-Reviewer-QS · 2026-02-20
77.1%
#21651: fix(gateway): token fallback + operator.admin scope superset in pai...
by lan17 · 2026-02-20
76.9%