refactor(whatsapp): centralize account connection lifecycle#65427
Conversation
🔒 Aisle Security AnalysisWe found 3 potential security issue(s) in this PR:
1. 🟠 Arbitrary directory deletion via unvalidated authDir in logoutWeb()
Description
With the new shared login flow ( Key points:
Vulnerable code: const resolvedAuthDir = resolveUserPath(params.authDir ?? resolveDefaultWebAuthDir());
...
await fs.rm(resolvedAuthDir, { recursive: true, force: true });RecommendationConstrain Suggested approach:
Example: import path from "node:path";
const base = path.resolve(path.join(resolveOAuthDir(), "whatsapp"));
const candidate = path.resolve(resolveUserPath(params.authDir ?? resolveDefaultWebAuthDir()));
const rel = path.relative(base, candidate);
if (rel.startsWith("..") || path.isAbsolute(rel) || rel === "") {
throw new Error(`Refusing to delete authDir outside base: ${candidate}`);
}
await fs.rm(candidate, { recursive: true, force: true });Additionally:
2. 🟠 Global Symbol.for registry allows in-process hijacking of WhatsApp connection controller (listener interception)
DescriptionThe WhatsApp extension stores connection controllers in a global
Impact:
Vulnerable code: const CONNECTION_REGISTRY_KEY = Symbol.for("openclaw.whatsapp.connectionControllerRegistry");
...
getConnectionRegistryState().controllers.set(accountId, controller);RecommendationAvoid using a public global registry keyed by Options (pick one appropriate to your architecture):
// generated/stored only in trusted host code
const REGISTRY_CAPABILITY = Symbol("openclaw.whatsapp.registry.capability");
export function registerWhatsAppConnectionController(
capability: symbol,
accountId: string,
controller: WhatsAppConnectionControllerHandle,
) {
if (capability !== REGISTRY_CAPABILITY) throw new Error("unauthorized");
getConnectionRegistryState().controllers.set(accountId, controller);
}
Additionally:
3. 🟡 CLI/log injection via unescaped WhatsApp accountId in formatted command hint
Description
Impact:
Vulnerable code: throw new Error(
`... link WhatsApp with: ${formatCliCommand(`openclaw channels login --channel whatsapp --account ${resolvedAccountId}`)}.`,
);RecommendationConstrain or safely render Options:
import { normalizeAccountId } from "openclaw/plugin-sdk/account-core";
const resolvedAccountId = normalizeAccountId(accountId ?? resolveDefaultWhatsAppAccountId(cfg));
const cmd = formatCliCommand(
`openclaw channels login --channel whatsapp --account ${shellQuote(resolvedAccountId)}`,
);Additionally, consider stripping ASCII control characters (e.g., Analyzed PR: #65427 at commit Last updated on: 2026-04-12T18:07:55Z |
Greptile SummaryThis PR centralizes WhatsApp account connection lifecycle into a new Confidence Score: 5/5Safe to merge — no logic bugs found; all P0/P1 concerns from prior rounds are resolved. The central lifecycle refactor is internally consistent: No files require special attention. Reviews (3): Last reviewed commit: "fix(whatsapp): isolate controller regist..." | Re-trigger Greptile |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 25ddce6133
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
Follow-up on bot review after the latest push (
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5b6c969455
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
Follow-up on the second review round after the latest push (
|
|
Codex Review: Didn't find any major issues. Nice work! ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
b2cdaf9 to
97669a7
Compare
47addbc to
7016cee
Compare
7016cee to
aee6b61
Compare
…#65427) * refactor(whatsapp): centralize account connection lifecycle * fix(whatsapp): harden controller open failure cleanup * refactor(whatsapp): remove active listener fallback path * fix(whatsapp): isolate controller registry state * debug(whatsapp): trace typing presence updates * docs(changelog): add whatsapp lifecycle fix note * debug(whatsapp): log global presence mode * chore(whatsapp): remove debug presence logs --------- Co-authored-by: Vincent Koc <[email protected]>
…#65427) * refactor(whatsapp): centralize account connection lifecycle * fix(whatsapp): harden controller open failure cleanup * refactor(whatsapp): remove active listener fallback path * fix(whatsapp): isolate controller registry state * debug(whatsapp): trace typing presence updates * docs(changelog): add whatsapp lifecycle fix note * debug(whatsapp): log global presence mode * chore(whatsapp): remove debug presence logs --------- Co-authored-by: Vincent Koc <[email protected]>
…#65427) * refactor(whatsapp): centralize account connection lifecycle * fix(whatsapp): harden controller open failure cleanup * refactor(whatsapp): remove active listener fallback path * fix(whatsapp): isolate controller registry state * debug(whatsapp): trace typing presence updates * docs(changelog): add whatsapp lifecycle fix note * debug(whatsapp): log global presence mode * chore(whatsapp): remove debug presence logs --------- Co-authored-by: Vincent Koc <[email protected]>
…#65427) * refactor(whatsapp): centralize account connection lifecycle * fix(whatsapp): harden controller open failure cleanup * refactor(whatsapp): remove active listener fallback path * fix(whatsapp): isolate controller registry state * debug(whatsapp): trace typing presence updates * docs(changelog): add whatsapp lifecycle fix note * debug(whatsapp): log global presence mode * chore(whatsapp): remove debug presence logs --------- Co-authored-by: Vincent Koc <[email protected]>
…#65427) * refactor(whatsapp): centralize account connection lifecycle * fix(whatsapp): harden controller open failure cleanup * refactor(whatsapp): remove active listener fallback path * fix(whatsapp): isolate controller registry state * debug(whatsapp): trace typing presence updates * docs(changelog): add whatsapp lifecycle fix note * debug(whatsapp): log global presence mode * chore(whatsapp): remove debug presence logs --------- Co-authored-by: Vincent Koc <[email protected]>
…#65427) * refactor(whatsapp): centralize account connection lifecycle * fix(whatsapp): harden controller open failure cleanup * refactor(whatsapp): remove active listener fallback path * fix(whatsapp): isolate controller registry state * debug(whatsapp): trace typing presence updates * docs(changelog): add whatsapp lifecycle fix note * debug(whatsapp): log global presence mode * chore(whatsapp): remove debug presence logs --------- Co-authored-by: Vincent Koc <[email protected]>
Summary
auto-reply/monitor,inbound/monitor,active-listener,login, andlogin-qr, so socket state, reconnect state, timers, and login recovery could drift apart.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Root Cause (if applicable)
Regression Test Plan (if applicable)
extensions/whatsapp/src/login.test.tsextensions/whatsapp/src/login.coverage.test.tsextensions/whatsapp/src/login-qr.test.tsextensions/whatsapp/src/active-listener.test.tsextensions/whatsapp/src/monitor-inbox.streams-inbound-messages.test.tsextensions/whatsapp/src/auto-reply.web-auto-reply.connection-and-logging.e2e.test.tsUser-visible / Behavior Changes
None.
Diagram (if applicable)
Security Impact (required)
Yes/No) NoYes/No) NoYes/No) NoYes/No) NoYes/No) NoYes, explain risk + mitigation:Repro + Verification
Environment
Steps
Expected
Actual
Evidence
Human Verification (required)
Review Conversations
Compatibility / Migration
Yes/No) YesYes/No) NoYes/No) NoRisks and Mitigations
main.