Skip to content

fix(security): role-gate WhatsApp account routes (decrypted-token exposure) - #4

Merged
sathyaprakash000 merged 1 commit into
mainfrom
fix/whatsapp-accounts-authz
May 25, 2026
Merged

fix(security): role-gate WhatsApp account routes (decrypted-token exposure)#4
sathyaprakash000 merged 1 commit into
mainfrom
fix/whatsapp-accounts-authz

Conversation

@sathyaprakash000

@sathyaprakash000 sathyaprakash000 commented May 25, 2026

Copy link
Copy Markdown
Contributor

P0 #1 from the security audit (lane 02, CRITICAL).

whatsappAccounts.js used a stub adminOnly that only checked req.user (a stale 'roles were removed' note), so any authenticated non-admin could:

  • read a live decrypted Meta access token via GET /api/whatsapp-accounts/:id?reveal=1
  • create / update / delete WhatsApp accounts

Fix: use the role-gated adminOnly from middleware/access.js on :id(reveal)/POST/PUT/DELETE. The list and by-phone picker routes stay open to all authenticated users — they return masked metadata only, no token.

…osure)

whatsappAccounts.js shipped a stub adminOnly that only checked req.user (a
stale 'roles were removed' assumption). The system does have roles
(admin/bda_sales/viewer, permissions.js + migration 031), so any logged-in
non-admin could read a live, DECRYPTED Meta access token via
GET /api/whatsapp-accounts/:id?reveal=1, and create/update/delete accounts.

Use the role-gated adminOnly from middleware/access.js for :id (reveal),
POST, PUT, DELETE. The list and by-phone picker routes stay open to all
authenticated users since they return masked metadata only (no token).

Audit ref: REVIEW.md P0 #1 (lane 02 CRITICAL + HIGHs).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: KingArthur000 <sathyaprakashelango@gmail.com>
@sathyaprakash000
sathyaprakash000 merged commit 4accbcb into main May 25, 2026
9 checks passed
@sathyaprakash000
sathyaprakash000 deleted the fix/whatsapp-accounts-authz branch May 25, 2026 03:14
sathyaprakash000 added a commit that referenced this pull request May 25, 2026
… deploy docs (#5)

Batch D — 5 audit Criticals + related:
- auth.js/crypto.js: production guards now reject the .env.example placeholder
  secrets and any value < 32 chars (not just the empty/dev-default), so a
  self-hoster copying .env.example unchanged can't run prod with public keys.
- .env.example: add POSTGRES_PASSWORD (+ matching DATABASE_URL) and META_APP_SECRET;
  document the >=32-char / no-placeholder requirement + openssl generation.
- Caddyfile: replace the real domain forgechat.akilsadik.live with
  forgechat.example.com + an explicit 'replace with your domain' note.
- DEPLOY.md: fix wrong env var names (FORGECRM_JWT_SECRET -> JWT_SECRET,
  FORGECRM_META_WEBHOOK_VERIFY_TOKEN -> META_WEBHOOK_VERIFY_TOKEN), drop the
  unused COOKIE_PARENT_DOMAINS, add POSTGRES_PASSWORD/META_APP_SECRET.
- admin seed: write the generated one-time password to a 0600 file instead of
  stdout (avoids credential persistence in log aggregators).
- health check: backend route is /health (not /api/health); add an nginx
  location so it's reachable externally, and fix both deploy guides' smoke test.

Audit refs: REVIEW.md P0 #4,#5,#6,#7,#8 (lanes 04,24,25).

Signed-off-by: KingArthur000 <sathyaprakashelango@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant