T09 · Insecure Skill Coding Practices
- Location
docs/03-prewarm-outbound.md:43- Finding
Unauthenticated Outbound Endpoint Permits Arbitrary Billable Calls
- Content
View full analysis
{ const { to, prospectContext } = req.body; const callId = crypto.randomUUID(); ``` ```javascript // Place the call const call = await twilioClient.calls.create({ from: process.env.TWILIO_PHONE_NUMBER, to, twiml: ``, statusCallback: `https://${DOMAIN}/call-status`, statusCallbackMethod: "POST", statusCallbackEvent: ["completed", "no-answer", "busy", "failed"], }); session.callSid = call.sid; callSidToCallId.set(call.sid, callId); res.json({ callSid: call.sid, callId }); ``` ### Technical Analysis The reference handler accepts the destination number and prospect context directly from the HTTP request body, then uses privileged Twilio credentials to place a call. No authentication, campaign-level authorization, E.164 validation, destination restrictions, request schema validation, quota, or rate limit is demonstrated. Because the endpoint performs a billable external action, possession of network access to the route is sufficient to exercise the application's Twilio privileges. The untrusted `prospectContext` is also passed into the session prompt elsewhere in the handler, creating an additional caller-controlled model-context boundary. ### Attack Path 1. An attacker identifies the publicly reachable `/outbound-call` endpoint. 2. The attacker submits a POST request containing an attacker-selected `to` number, potentially including premium-rate or high-cost international destinations. 3. The server creates an OpenAI session and invokes `twilioClient.calls.create()` with its configured Twilio credentials. 4. The attacker repeats the re ...[truncated 830 chars]- Remediation
View remediation
