Skip to content

fix(sms): validate inbound Twilio webhook signatures#6606

Closed
MestreY0d4-Uninter wants to merge 2 commits into
NousResearch:mainfrom
MestreY0d4-Uninter:fix/sms-twilio-webhook-validation
Closed

fix(sms): validate inbound Twilio webhook signatures#6606
MestreY0d4-Uninter wants to merge 2 commits into
NousResearch:mainfrom
MestreY0d4-Uninter:fix/sms-twilio-webhook-validation

Conversation

@MestreY0d4-Uninter

Copy link
Copy Markdown
Contributor

Summary

  • validate inbound Twilio SMS webhooks before scheduling message handling
  • reject missing or forged X-Twilio-Signature requests with a fast 403 response
  • add focused unit and integration-style regression tests for Twilio signature enforcement

Problem

The SMS adapter accepted any POST to /webhooks/twilio and immediately scheduled handle_message() without verifying that the request actually came from Twilio.

That meant anyone who knew the webhook URL could forge inbound SMS payloads and impersonate arbitrary phone numbers.

Investigation

Validated in a clean isolated worktree from current origin/main:

  • searched for an existing issue/PR matching this specific Twilio signature-validation gap and did not find one
  • confirmed gateway/platforms/sms.py::_handle_webhook() parsed form data and queued work without checking X-Twilio-Signature
  • checked Twilio Python best practice: validate the full request URL + POST vars against the Auth Token (equivalent to RequestValidator.validate(url, post_vars, signature))
  • got a second opinion via Claude Code, which recommended the same minimal fix shape and test coverage

Fix

  • add _validate_twilio_signature() to SmsAdapter
  • validate X-Twilio-Signature immediately after parsing the form body
  • return empty TwiML with HTTP 403 on invalid or missing signature
  • keep the webhook non-blocking for valid requests

Validation

Ran locally in the isolated worktree:

  • pytest tests/gateway/test_sms.py -q -o addopts=
  • python -m py_compile gateway/platforms/sms.py tests/gateway/test_sms.py

Result:

  • 29 passed

Tests added

  • signature helper unit tests:
    • valid signature
    • wrong signature
    • empty signature
    • tampered body
    • wrong URL
  • webhook enforcement tests:
    • missing signature -> 403
    • invalid signature -> 403
    • valid signature -> 200

@MestreY0d4-Uninter

Copy link
Copy Markdown
Contributor Author

Atualizei a branch com dois ajustes em cima da review:

  • removi a duplicação do helper de validação
  • a reconstrução da URL para assinatura agora prefere X-Forwarded-* quando presente, reduzindo fragilidade atrás de proxy/reverse proxy

Também adicionei cobertura para URL externa reconstruída / forwarded headers.

Validação local:

  • pytest tests/gateway/test_sms.py -q -o addopts=
  • python3 -m py_compile gateway/platforms/sms.py tests/gateway/test_sms.py

Resultado: 32 passed

@MestreY0d4-Uninter

Copy link
Copy Markdown
Contributor Author

Changes da review já aplicados na branch e revalidados localmente.

Status atual: pronta para re-review.

O que ficou coberto:

  • remoção da duplicação do helper de validação
  • reconstrução da URL priorizando X-Forwarded-* quando presente
  • testes adicionais para proxy/forwarded headers

Observação: os checks vermelhos que restam continuam aparecendo em áreas amplas do repo fora do escopo deste diff; não estou tratando isso, isoladamente, como regressão desta PR.

@teknium1

Copy link
Copy Markdown
Contributor

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

@teknium1 teknium1 closed this Apr 11, 2026
@MestreY0d4-Uninter MestreY0d4-Uninter deleted the fix/sms-twilio-webhook-validation branch April 27, 2026 01:38
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.

2 participants