refactor(whatsapp): centralize account policy#70922
Conversation
🔒 Aisle Security AnalysisWe found 2 potential security issue(s) in this PR:
1. 🟠 WhatsApp outbound allowlist bypass when allowFrom is empty (default allow-all)
DescriptionThe outbound target authorization logic treats an empty
Vulnerable code: if (hasWildcard || allowList.length === 0) {
return { ok: true, to: normalizedTo };
}This is security-sensitive because other call paths (e.g., action authorization via RecommendationAdopt a default-deny posture for outbound direct messages unless an explicit allow rule exists. Suggested change:
// deny-by-default unless wildcard or explicit match
if (hasWildcard) {
return { ok: true, to: normalizedTo };
}
if (allowList.length === 0) {
return { ok: false, error: whatsappAllowFromPolicyError(normalizedTo) };
}
if (allowList.includes(normalizedTo)) {
return { ok: true, to: normalizedTo };
}
return { ok: false, error: whatsappAllowFromPolicyError(normalizedTo) };Also update documentation/tests to reflect the intended policy (and ensure configs without 2. 🟡 Outbound allowFrom policy bypass: any WhatsApp group JID is always authorized
Description
This allows an actor who can invoke WhatsApp send actions to message arbitrary groups (if they can supply/guess a group JID), even when outbound messaging is restricted to specific contacts via Vulnerable code: if (isWhatsAppGroupJid(normalizedTo)) {
return { ok: true, to: normalizedTo };
}RecommendationApply allowlist enforcement consistently to group JIDs, or introduce a separate, explicit configuration for allowed group targets. Example: require group JIDs to be explicitly allowlisted unless a dedicated const isGroup = isWhatsAppGroupJid(normalizedTo);
if (hasWildcard || allowList.length === 0) {
return { ok: true, to: normalizedTo };
}
// Enforce allowlist for both users and groups
if (allowList.includes(normalizedTo)) {
return { ok: true, to: normalizedTo };
}
return { ok: false, error: whatsappAllowFromPolicyError(normalizedTo) };If the intent is to keep groups open by default, make that an explicit policy (e.g., Analyzed PR: #70922 at commit Last updated on: 2026-04-24T04:33:19Z |
Greptile SummaryThis PR centralizes WhatsApp account policy resolution into a new Confidence Score: 5/5Safe to merge — all callers are covered by tests, behaviour is preserved, and the normalization change (trimming whitespace entries) is a net fix. No P0/P1 findings. The one subtle behaviour difference — normalizeConfiguredAllowEntries now trims and filters blank entries before they reach downstream comparators, whereas the old inbound-policy.ts deferred this to normalizeE164 at comparison time — is a correctness improvement verified by the new account-policy tests. The groupAllowFrom fallback moved from explicit pre-processing into resolveEffectiveAllowFromLists, which the 'falls back groupAllowFrom to allowFrom when unset' test confirms works identically. No files require special attention. Reviews (1): Last reviewed commit: "refactor(whatsapp): centralize account p..." | Re-trigger Greptile |
|
Aisle follow-up: I reviewed both reported items against this PR diff and
I agree both topics can be considered for separate hardening/policy follow-up, especially if we want stricter group outbound authorization or canonical account-id validation. I do not think either is a patch-introduced regression in this centralization PR. |
eaf3288 to
18310f4
Compare
18310f4 to
844b652
Compare
|
Codex review: found issues before merge. Reviewed July 3, 2026, 3:00 AM ET / 07:00 UTC. Summary PR surface: Source +41, Tests +237. Total +278 across 7 files. Reproducibility: not applicable. this is a behavior-preserving refactor PR rather than a bug report. The reviewable checks are current-main mergeability, source parity, and authorization-policy sequencing. Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Refresh the account-policy seam on current main, replace broad config-runtime imports with narrow Plugin SDK subpaths, preserve current WhatsApp send/inbound behavior, and land only after maintainers accept the sequencing with adjacent WhatsApp authorization work. Do we have a high-confidence way to reproduce the issue? Not applicable: this is a behavior-preserving refactor PR rather than a bug report. The reviewable checks are current-main mergeability, source parity, and authorization-policy sequencing. Is this the best way to solve the issue? No for the submitted branch state. A WhatsApp-local account-policy seam is a plausible cleanup, but this branch conflicts with current main and imports from a config SDK barrel that current main's boundary guard rejects. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 8ed6c78b7891. Label changesLabel justifications:
Evidence reviewedPR surface: Source +41, Tests +237. Total +278 across 7 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
Summary
extensions/whatsapp/src/account-policy.tsPreserved behavior
defaultAccountselection and omitted-account fallback behavioraccounts.defaultinheritance rules, including non-inheritance of default-onlyauthDirandselfChatModeTests
pnpm test extensions/whatsapp/src/account-policy.test.tspnpm test extensions/whatsapp/src/inbound/access-control.test.tspnpm test extensions/whatsapp/src/heartbeat-recipients.test.tspnpm test extensions/whatsapp/src/action-runtime.test.tspnpm test extensions/whatsapp/src/send.test.tspnpm test extensions/whatsapp/src/accounts.test.tspnpm check:changedNotes