🔧 update: security hardening and deduplication#3
Conversation
Wire up the existing validateTwilioSignature() helper as express middleware on the Twilio webhook router. Every incoming request is now verified against the X-Twilio-Signature header before any message processing occurs, preventing forged webhook calls. Requires a new TWILIO_WEBHOOK_URL env var (the full public-facing URL Twilio posts to), documented in .env.example. https://claude.ai/code/session_01KnaWLH6KQiPH5yzDK5hbX7
Add package overrides to force safe versions of three vulnerable transitive dependencies: - axios ^1.15.0 (was 1.13.5 via twilio) — fixes critical SSRF via NO_PROXY bypass and cloud metadata exfiltration via header injection - follow-redirects ^1.16.0 (was 1.15.11 via axios) — fixes moderate auth header leakage on cross-domain redirects - path-to-regexp ^8.4.0 (was 8.3.0 via express/router) — fixes high ReDoS via sequential optional groups and multiple wildcards All 5 vulnerabilities confirmed resolved via bun audit. https://claude.ai/code/session_01KnaWLH6KQiPH5yzDK5hbX7
- wgtechlabs/container-build-flow-action v1.3.1 → v1.7.1 - wgtechlabs/release-build-flow-action v1.6.0 → v1.7.0 https://claude.ai/code/session_01KnaWLH6KQiPH5yzDK5hbX7
Replace four inline res...send('<Response></Response>') calls with a
shared sendEmptyTwiML(res, status?) helper to avoid drift and make
future response changes easier.
https://claude.ai/code/session_01KnaWLH6KQiPH5yzDK5hbX7
The function was defined independently in customer-store.ts and unthread.ts with a subtle type signature difference (one accepted null, the other didn't), risking logic drift if statuses were ever updated in one file but not the other. Moved to types.ts with the wider string | null | undefined signature and imported in both service files. https://claude.ai/code/session_01KnaWLH6KQiPH5yzDK5hbX7
🔥 Container Build Complete - Patch BuildBuild Status: ✅ Success 📦 Pull ImageDocker Hub: docker pull wgtechlabs/unthread-whatsapp-bot:patch-0a346ccGHCR: docker pull ghcr.io/wgtechlabs/unthread-whatsapp-bot:patch-0a346cc📋 Build Details
🏷️ Image Tags• 🔍 Testing Your Changes
🚀 Quick Start# Pull and run the container
Docker Hub: docker pull wgtechlabs/unthread-whatsapp-bot:patch-0a346cc
docker run <your-options> <image>🔒 Security Scan Results📋 Pre-Build Security Checks✅ Source Code Scan: 0 vulnerabilities found 🐳 Container Image Vulnerabilities
📊 Detailed Security ReportsView detailed vulnerability reports in the GitHub Security tab. 🤖 Powered by Container Build Flow Action vv1.7.1 |
There was a problem hiding this comment.
Pull request overview
This PR centralizes the isReusableConversationStatus helper into src/types.ts to avoid duplicated, diverging implementations, and additionally tightens Twilio webhook handling by validating the X-Twilio-Signature header (with accompanying config/dependency updates).
Changes:
- Moved
isReusableConversationStatusintosrc/types.tsand updatedcustomer-store.ts/unthread.tsto import it. - Added Twilio webhook signature validation middleware and a small helper for sending empty TwiML responses.
- Updated dependencies/lockfile, GitHub workflow action versions, and added
TWILIO_WEBHOOK_URLto config +.env.example.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/types.ts |
Adds shared isReusableConversationStatus helper export. |
src/services/unthread.ts |
Removes local helper and imports shared status helper. |
src/services/customer-store.ts |
Removes local helper and imports shared status helper. |
src/routes/twilio-webhook.ts |
Adds Twilio signature validation middleware and sendEmptyTwiML helper. |
src/config.ts |
Introduces required config.twilio.webhookUrl env var. |
package.json |
Bumps runtime/dev dependencies and adds overrides. |
bun.lock |
Updates lockfile to reflect dependency bumps and overrides. |
.github/workflows/release.yml |
Bumps release-build-flow-action version. |
.github/workflows/container.yml |
Bumps container-build-flow-action version. |
.env.example |
Documents new TWILIO_WEBHOOK_URL variable. |
Summary
This PR consolidates security hardening work and a maintainability fix from this session.
🔒 Twilio webhook signature validation
Wires up the existing
validateTwilioSignature()helper as express middleware on the Twilio webhook router. Every incoming request is verified against theX-Twilio-Signatureheader before any message processing occurs, preventing forged webhook calls.Requires a new
TWILIO_WEBHOOK_URLenv var (the full public-facing URL Twilio posts to) — documented in.env.example. The server will refuse to start without it to prevent running with signature validation silently disabled.Also introduces a
sendEmptyTwiML(res, status?)helper to centralize the repeated<Response></Response>string across all response branches.🔒 Dependency security overrides
Adds
overridesinpackage.jsonto force safe versions of vulnerable transitive dependencies (bun auditconfirmed 5 vulnerabilities resolved):axios(via twilio)path-to-regexp(via express/router)follow-redirects(via axios)⚙️ GitHub Actions updates
wgtechlabs/container-build-flow-actionv1.3.1 → v1.7.1wgtechlabs/release-build-flow-actionv1.6.0 → v1.7.0🔧 Deduplicate
isReusableConversationStatusisReusableConversationStatuswas defined independently incustomer-store.tsandunthread.tswith a subtle type signature difference. Moved tosrc/types.tsas a shared export — no runtime behavior change.https://claude.ai/code/session_01KnaWLH6KQiPH5yzDK5hbX7