Skip to content

fix(security): validate Twilio signature in SMS webhook (RCE fix for #7089)#7223

Closed
Linux2010 wants to merge 1 commit into
NousResearch:mainfrom
Linux2010:fix/issue-7089-sms-webhook-rce-v2
Closed

fix(security): validate Twilio signature in SMS webhook (RCE fix for #7089)#7223
Linux2010 wants to merge 1 commit into
NousResearch:mainfrom
Linux2010:fix/issue-7089-sms-webhook-rce-v2

Conversation

@Linux2010

Copy link
Copy Markdown
Contributor

What broke

SMS webhook endpoint /webhooks/twilio accepts ANY HTTP POST request without validating X-Twilio-Signature header. Attackers can forge requests to bypass authorization and execute arbitrary commands with full local OS privileges.

Severity: CVSS 9.8 Critical (Remote Code Execution)

Root cause

_handle_webhook() in gateway/platforms/sms.py parses POST body and extracts From/Body fields without checking the HMAC-SHA1 signature that Twilio provides in X-Twilio-Signature header.

Why this fix is minimal

Added _validate_twilio_signature() method (35 lines) and call it at the START of request processing:

  • Legitimate Twilio-signed requests continue working unchanged
  • Forged requests get HTTP 403 Forbidden
  • No behavior change for valid users
  • No changes to downstream message handling
  • No opportunistic refactoring

Added SMS_WEBHOOK_URL env var for reverse proxy scenarios.

What I tested

Added regression test suite in tests/test_sms_signature_security.py:

Test Coverage
test_valid_signature_passes Legitimate Twilio request accepted
test_missing_signature_rejected No header → rejected
test_invalid_signature_rejected Wrong signature → rejected
test_tampered_body_rejected Body modified → rejected
test_signature_injection_attack_rejected Extra params → rejected
test_configured_webhook_url_used Reverse proxy scenario
test_no_configured_url_uses_request_url Direct access scenario

Python syntax validated with py_compile.

What I intentionally did not change

  • No changes to webhook URL structure
  • No changes to response format (TwiML)
  • No changes to message processing logic
  • Did not add IP allowlist (optional hardening, separate issue)
  • Did not add HTTPS enforcement (reverse proxy responsibility)

Backward Compatibility

Scenario Config needed
Direct access None
Reverse proxy SMS_WEBHOOK_URL=https://example.com/webhooks/twilio

Security Impact

Before After
Any HTTP POST accepted Only Twilio-signed requests processed
Attacker can spoof From field Signature validates request authenticity
CVSS 9.8 RCE Attack vector eliminated

Rebased on upstream/main (7e60b09) - clean branch with only SMS webhook fix.

Fixes #7089

## What broke
SMS webhook endpoint /webhooks/twilio accepts ANY HTTP POST request
without validating X-Twilio-Signature header. Attackers can forge
requests to bypass authorization and execute arbitrary commands with
full local OS privileges (CVSS 9.8 Critical RCE).

## Root cause
_handle_webhook() in gateway/platforms/sms.py parses POST body and
extracts From/Body fields without checking the HMAC-SHA1 signature
that Twilio provides in X-Twilio-Signature header.

## Why this fix is minimal
Added _validate_twilio_signature() method (35 lines) and call it at
the START of request processing. Legitimate Twilio-signed requests
continue working unchanged. Forged requests get HTTP 403.

Added SMS_WEBHOOK_URL env var for reverse proxy scenarios where
the public URL differs from internal URL (HTTP vs HTTPS, port, etc).

- No behavior change for valid users
- No changes to downstream message handling
- No opportunistic refactoring
- Added regression test suite (8 test cases)

## What I tested
- Python syntax validation (py_compile)
- Test suite covers: valid signature, missing signature, invalid
  signature, tampered body, parameter injection attacks
- Test suite covers: configured webhook URL vs request URL

## What I intentionally did not change
- No changes to webhook URL structure
- No changes to response format (TwiML)
- No changes to message processing logic
- Did not add IP allowlist (optional hardening, separate issue)
- Did not add HTTPS enforcement (reverse proxy responsibility)

## Backward Compatibility
- Users without reverse proxy: no config change needed
- Users with reverse proxy: set SMS_WEBHOOK_URL to public URL
- Example: SMS_WEBHOOK_URL=https://example.com/webhooks/twilio

Fixes NousResearch#7089
@teknium1

Copy link
Copy Markdown
Contributor

This vulnerability has been fixed in PR #7933 (merged). Thanks for the contribution, @Linux2010.

@teknium1 teknium1 closed this Apr 11, 2026
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.

[Bug]: Unauthenticated Remote Code Execution via SMS Webhook — Missing Twilio Signature Validation

2 participants