#10231: fix(voice-call): escape locale/language params in TwiML to prevent XML injection
channel: voice-call
stale
Cluster:
TwiML Security and Fixes
## Fix Summary
- Apply `escapeXml()` to `input.locale` in `playTts()` and `input.language` in `startListening()` TwiML templates
- These parameters were interpolated directly into XML attributes without escaping, unlike `webhookUrl` and `input.text` which were already escaped
- The Plivo provider already escapes its language parameter correctly; this aligns Twilio with the same pattern
## Issue Linkage
Fixes #10229
## Security Snapshot
| Metric | Value |
|--------|-------|
| **Score** | 8.5 / 10.0 |
| **Severity** | High |
| **Vector** | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:H/A:N |
## Implementation Details
### Files Changed
- `extensions/voice-call/src/providers/twilio.ts` (+2/-2)
### Technical Analysis
- Apply `escapeXml()` to `input.locale` in `playTts()` and `input.language` in `startListening()` TwiML templates
## Validation Evidence
- Command: `pnpm build`
- Status: passed
## Risk and Compatibility
non-breaking; compatibility impact was not explicitly documented in the original PR body.
## AI-Assisted Disclosure
- AI-assisted: yes
- Model: Claude Opus 4.6
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
- Escapes user-controlled `locale` and `language` values before interpolating them into Twilio TwiML XML attributes.
- Updates Twilio provider’s `<Say>` and `<Gather>` templates to use the shared `escapeXml()` utility (already used for `input.text` and `webhookUrl`).
- Aligns Twilio behavior with other providers by preventing XML attribute injection via language/locale fields.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk.
- Change is narrowly scoped to escaping XML attribute values in TwiML using an existing `escapeXml()` helper; it preserves previous defaults (`en-US`) and matches existing escaping already applied to other interpolated fields.
- extensions/voice-call/src/providers/twilio.ts
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#10238: Security: Fix TwiML injection via unescaped locale/language/voice p...
by StreetJammer · 2026-02-06
93.8%
#8297: fix(voice-call): prevent empty TwiML for non-in-progress outbound c...
by vishaltandale00 · 2026-02-03
76.4%
#7652: fix(voice-call): fix Telnyx transcription (STT) not working
by tturnerdev · 2026-02-03
75.9%
#16992: fix(gateway): escape XML entities in file.filename to prevent promp...
by AI-Reviewer-QS · 2026-02-15
72.6%
#21050: security(voice-call): path-based stream token for Twilio WebSocket ...
by richvincent · 2026-02-19
72.4%
#7704: fix(voice-call): add authentication to WebSocket media stream endpoint
by coygeek · 2026-02-03
72.3%
#20058: feat(voice-call): add Twilio non-US region support (region/edge con...
by giumex · 2026-02-18
71.6%
#21110: fix(tts): deliver audio via structured mediaUrl instead of MEDIA: t...
by hydro13 · 2026-02-19
70.8%
#8251: fix(voice-call): remove redundant transcript from extraSystemPrompt
by geodeterra · 2026-02-03
70.5%
#6128: Fail closed when Telnyx webhook public key is missing (voice-call p...
by yueyueL · 2026-02-01
70.4%