Skip to content

🔧 update: security hardening and deduplication#3

Merged
warengonzaga merged 5 commits into
mainfrom
fix/deduplicate-reusable-conversation-status
Apr 15, 2026
Merged

🔧 update: security hardening and deduplication#3
warengonzaga merged 5 commits into
mainfrom
fix/deduplicate-reusable-conversation-status

Conversation

@warengonzaga

@warengonzaga warengonzaga commented Apr 14, 2026

Copy link
Copy Markdown
Member

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 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. 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 overrides in package.json to force safe versions of vulnerable transitive dependencies (bun audit confirmed 5 vulnerabilities resolved):

Package Was Now Severity
axios (via twilio) 1.13.5 1.15.0 2× Critical
path-to-regexp (via express/router) 8.3.0 8.4.2 1× High, 1× Moderate
follow-redirects (via axios) 1.15.11 1.16.0 1× Moderate

⚙️ GitHub Actions updates

  • wgtechlabs/container-build-flow-action v1.3.1 → v1.7.1
  • wgtechlabs/release-build-flow-action v1.6.0 → v1.7.0

🔧 Deduplicate isReusableConversationStatus

isReusableConversationStatus was defined independently in customer-store.ts and unthread.ts with a subtle type signature difference. Moved to src/types.ts as a shared export — no runtime behavior change.

https://claude.ai/code/session_01KnaWLH6KQiPH5yzDK5hbX7

claude added 5 commits April 14, 2026 20:15
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
Copilot AI review requested due to automatic review settings April 14, 2026 20:35
@github-actions

Copy link
Copy Markdown

🔥 Container Build Complete - Patch Build

Build Status: ✅ Success
Flow Type: patch
Description: Hotfix for production


📦 Pull Image

Docker Hub: docker pull wgtechlabs/unthread-whatsapp-bot:patch-0a346cc
GHCR: docker pull ghcr.io/wgtechlabs/unthread-whatsapp-bot:patch-0a346cc

📋 Build Details

Property Value
Flow Type patch
Commit 9e582da
Registry Docker Hub + GHCR

🏷️ Image Tags

wgtechlabs/unthread-whatsapp-bot:patch-0a346cc
ghcr.io/wgtechlabs/unthread-whatsapp-bot:patch-0a346cc


🔍 Testing Your Changes

  1. Pull the image using one of the commands above
  2. Run the container with your test configuration
  3. Verify the changes work as expected
  4. Report any issues in this PR

🚀 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
Dockerfile Scan: 0 misconfigurations found

🐳 Container Image Vulnerabilities

Severity Count
Total 0

📊 Detailed Security Reports

View detailed vulnerability reports in the GitHub Security tab.


🤖 Powered by Container Build Flow Action vv1.7.1
💻 with ❤️ by Waren Gonzaga under WG Technology Labs, and Him 🙏

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 isReusableConversationStatus into src/types.ts and updated customer-store.ts / unthread.ts to 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_URL to 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.

Comment thread src/routes/twilio-webhook.ts
Comment thread src/config.ts
@warengonzaga warengonzaga changed the title 🔧 update: deduplicate isReusableConversationStatus into shared types 🔧 update: security hardening and deduplication Apr 15, 2026
@warengonzaga warengonzaga merged commit b1062e7 into main Apr 15, 2026
6 checks passed
@warengonzaga warengonzaga deleted the fix/deduplicate-reusable-conversation-status branch April 15, 2026 03:22
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.

3 participants