Skip to content

fix(security): add Twilio signature validation to SMS webhook#6354

Closed
Alpaca1712 wants to merge 1 commit into
NousResearch:mainfrom
Alpaca1712:fix/sms-webhook-signature-validation
Closed

fix(security): add Twilio signature validation to SMS webhook#6354
Alpaca1712 wants to merge 1 commit into
NousResearch:mainfrom
Alpaca1712:fix/sms-webhook-signature-validation

Conversation

@Alpaca1712

@Alpaca1712 Alpaca1712 commented Apr 9, 2026

Copy link
Copy Markdown

Summary

  • Adds X-Twilio-Signature (HMAC-SHA1) validation to the SMS webhook endpoint (gateway/platforms/sms.py), closing a zero-authentication remote prompt injection vector.
  • Fail-closed design: requests are rejected when SMS_WEBHOOK_URL is unset, when the signature header is missing, or when the signature is invalid (403 + empty TwiML).
  • Handles Twilio's with-port / without-port signature ambiguity.
  • Warns at startup when SMS_WEBHOOK_URL is not configured.
  • New env var: SMS_WEBHOOK_URL — public URL of the webhook endpoint, required for signature recomputation.
  • 10 new tests covering valid signatures, missing/empty/wrong/forged signatures, trailing-slash normalization, port variants, wrong auth tokens, and tampered bodies.

Vulnerability

The /webhooks/twilio endpoint had no signature validation. An external attacker with no credentials could forge Twilio SMS webhook payloads that are injected directly into the agent's LLM context. Since there was no authentication, the attacker could inject arbitrary instructions that cause the agent to execute shell commands, read files, or exfiltrate data — a zero-auth remote code execution vector.

The compound attack chain can disable safety checks (HERMES_YOLO_MODE, HERMES_REDACT_SECRETS), then establish persistent credential exfiltration via cron jobs — all from a single forged HTTP POST.

Reported by Rocoto, an autonomous security agent for AI agents.

Test plan

  • Existing SMS tests pass
  • New TestTwilioSignatureValidation class passes (10 tests)
  • Forged webhook POST without valid signature returns 403
  • Valid Twilio-signed webhook POST is accepted
  • Adapter logs warning at startup when SMS_WEBHOOK_URL is unset
  • Adapter rejects all inbound webhooks when SMS_WEBHOOK_URL is unset (fail-closed)

Made with Cursor

The /webhooks/twilio endpoint accepted inbound POST requests with
zero authentication, allowing an external attacker to forge SMS
webhook payloads and inject arbitrary text into the agent's LLM
context.  This is a zero-auth remote prompt injection vector that
can chain into shell command execution, credential exfiltration,
and persistent compromise via cron jobs.

Fix:
- Validate X-Twilio-Signature (HMAC-SHA1) on every inbound webhook
  using the existing TWILIO_AUTH_TOKEN — no new dependencies.
- Fail-closed: requests are rejected when SMS_WEBHOOK_URL is unset,
  when the header is missing, or when the signature is invalid.
- Handle Twilio's with-port / without-port signature ambiguity.
- Return 403 with empty TwiML on rejection.
- Warn at startup when SMS_WEBHOOK_URL is not configured.

New env var:
- SMS_WEBHOOK_URL — public URL of the webhook endpoint, required
  for signature recomputation.

Reported by Rocoto (https://www.artoo.love/), an autonomous
security agent for AI agents.

Made-with: Cursor
@teknium1

Copy link
Copy Markdown
Contributor

This vulnerability has been fixed in PR #7933 (merged). Thanks for the contribution, @Alpaca1712 — your port variant handling approach was noted.

@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.

2 participants