Every CVE Search/ Get API key

CVE-2026-54695

Pipecat: Telephony WebSocket `/ws` Unauthenticated Call-Control Abuse via Attacker-Supplied Call SID

7.5 HighFix available

Pipecat is an open-source Python framework for building real-time voice and multimodal conversational agents. Prior to 1.4.0, the pipecat development runner registers a /ws WebSocket endpoint for telephony testing that accepts connections without authentication, reads an attacker-supplied callSid from a Twilio stream-start handshake in src/pipecat/runner/utils.py, and passes it to TwilioFrameSerializer so the server can issue an authenticated Twilio REST API hang-up request with the server operator's credentials; equivalent unauthenticated call-control sinks exist for Telnyx and Plivo. This issue is fixed in version 1.4.0.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
High
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
Low
Availability
High

Exploit likelihood

0.56%Up 0.2 points since Jul 10, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.5

Pipecat: Telephony WebSocket `/ws` Unauthenticated Call-Control Abuse via Attacker-Supplied Call SID

Pipecat is an open-source Python framework for building real-time voice and multimodal conversational agents. Prior to 1.4.0, the pipecat development runner registers a /ws WebSocket endpoint for telephony testing that accepts connections without authentication, reads an attacker-supplied callSid from a Twilio stream-start handshake in src/pipecat/runner/utils.py, and passes it to TwilioFrameSerializer so the server can issue an authenticated Twilio REST API hang-up request with the server operator's credentials; equivalent unauthenticated call-control sinks exist for Telnyx and Plivo. This issue is fixed in version 1.4.0.

Record
CVE-2026-54695
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:H
Weakness
CWE-862
Updated
2026-11-02
EUVDEUVD-2026-42673 7.5

Pipecat is an open-source Python framework for building real-time voice and multimodal conversational agents. Prior to 1.4.0, the pipecat development runner registers a /ws WebSocket endpoint for telephony testing that accepts connections without authentication, reads an attacker-supplied callSid from a Twilio stream-start handshake in src/pipecat/runner/utils.py, and passes it to TwilioFrameSerializer so the server can issue an authenticated Twilio REST API hang-up request with the server operator's credentials; equivalent unauthenticated call-control sinks exist for Telnyx and Plivo. This issue is fixed in version 1.4.0.

Record
EUVD-2026-42673
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:H
Updated
2026-11-02
GitHub AdvisoriesGHSA-j8cv-x86q-rj85 7.5

Pipecat: Telephony WebSocket `/ws` Unauthenticated Call-Control Abuse via Attacker-Supplied Call SID

Development Runner Telephony WebSocket /ws Unauthenticated Call-Control Abuse via Attacker-Supplied Call SID

Summary

The pipecat development runner registers a /ws WebSocket endpoint for telephony testing that accepts connections without any authentication. An unauthenticated remote attacker who can reach an exposed runner endpoint can connect to this endpoint, send a crafted Twilio handshake message containing an attacker-supplied callSid, and cause the server to issue an authenticated Twilio REST API hang-up request against that call SID using the server operator's own credentials. This may allow the attacker to forcibly terminate an active call on the victim's Twilio account if the attacker knows or obtains a valid call SID for that account. Equivalent unauthenticated call-control sinks exist for Telnyx and Plivo. Maintainers are evaluating the final CVSS 3.1 score.

Details

The pipecat development runner registers a WebSocket route at /ws (src/pipecat/runner/run.py:1116). When a client connects, the server immediately accepts the connection without performing any authentication or signature verification (run.py:1119):

await websocket.accept()   # run.py:1119 — no auth check before this point

After acceptance, the server reads the Twilio WebSocket stream-start handshake and extracts the callSid field verbatim from the attacker-controlled JSON payload (src/pipecat/runner/utils.py:223):

call_id: start_data.get("callSid")   # utils.py:223 — tainted, attacker-supplied

The tainted call_id is then passed directly into TwilioFrameSerializer alongside the server's own Twilio account credentials, which are read from environment variables (src/pipecat/runner/utils.py:513-517):

TwilioFrameSerializer(
    stream_sid=stream_id,
    call_sid=call_id,                          # TAINTED
    account_sid=os.getenv("TWILIO_ACCOUNT_SID"),  # server credential
    auth_token=os.getenv("TWILIO_AUTH_TOKEN"),     # server credential
)

TwilioFrameSerializer has auto_hang_up defaulting to True (src/pipecat/serializers/twilio.py:56). When the pipeline terminates and serializes an EndFrame or CancelFrame, _hang_up_call() is triggered (twilio.py:141-147). This method constructs a Twilio REST API URL containing the attacker-supplied call_sid and POSTs to it using the server's own credentials (twilio.py:196, twilio.py:206):

POST https://api.twilio.com/2010-04-01/Accounts/{account_sid}/Calls/{attacker_call_sid}.json
Authorization: Basic <base64(account_sid:auth_token)>
Body: Status=completed

The same unauthenticated call-control pattern exists for Telnyx (src/pipecat/serializers/telnyx.py:188, :195) and Plivo (src/pipecat/serializers/plivo.py:180, :187).

Although the runner defaults to localhost and is documented as a development runner, its telephony mode is commonly used with a public proxy hostname so that telephony providers can connect inbound calls. If the development runner is exposed to untrusted networks while configured with Twilio, Telnyx, or Plivo credentials, this becomes a realistic network-reachable attack surface.

PoC

Prerequisites

  • Docker (for building the isolated PoC image)
  • A clone of the pipecat repository at commit b982b45a7ae1e5ee99e4390ad5a116cdd9b4a8e2 placed at <context_root>/repo/
  • The files vuln-001/Dockerfile and vuln-001/poc.py present under <context_root>/

Step 1 — Build the Docker image

docker build \
  -f vuln-001/Dockerfile \
  -t vuln001-poc \
  reports/pypiAi_247_pipecat-ai__pipecat

The Dockerfile installs pipecat from the local repository clone, generates a self-signed TLS CA and server certificate for api.twilio.com, and registers that CA in the system trust store so that pipecat's aiohttp-based HTTP client accepts the mock server certificate.

Step 2 — Run the PoC

docker run --rm \
  --add-host api.twilio.com:127.0.0.1 \
 …
Record
GHSA-j8cv-x86q-rj85
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:H
Weakness
CWE-862
Updated
2026-11-02
NVD 7.5

Pipecat is an open-source Python framework for building real-time voice and multimodal conversational agents. Prior to 1.4.0, the pipecat development runner registers a /ws WebSocket endpoint for telephony testing that accepts connections without authentication, reads an attacker-supplied callSid from a Twilio stream-start handshake in src/pipecat/runner/utils.py, and passes it to TwilioFrameSerializer so the server can issue an authenticated Twilio REST API hang-up request with the server operator's credentials; equivalent unauthenticated call-control sinks exist for Telnyx and Plivo. This issue is fixed in version 1.4.0.

Record
CVE-2026-54695
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:H
CVSS 3.1
6.5 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:H
Weakness
CWE-862
Updated
2026-11-02
OSV 7.5

Pipecat: Telephony WebSocket `/ws` Unauthenticated Call-Control Abuse via Attacker-Supplied Call SID

Pipecat is an open-source Python framework for building real-time voice and multimodal conversational agents. Prior to 1.4.0, the pipecat development runner registers a /ws WebSocket endpoint for telephony testing that accepts connections without authentication, reads an attacker-supplied callSid from a Twilio stream-start handshake in src/pipecat/runner/utils.py, and passes it to TwilioFrameSerializer so the server can issue an authenticated Twilio REST API hang-up request with the server operator's credentials; equivalent unauthenticated call-control sinks exist for Telnyx and Plivo. This issue is fixed in version 1.4.0.

Record
CVE-2026-54695
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:H
Weakness
CWE-862
Updated
2026-11-02
OSVGHSA-j8cv-x86q-rj85 7.5

Pipecat: Telephony WebSocket `/ws` Unauthenticated Call-Control Abuse via Attacker-Supplied Call SID

Development Runner Telephony WebSocket /ws Unauthenticated Call-Control Abuse via Attacker-Supplied Call SID

Summary

The pipecat development runner registers a /ws WebSocket endpoint for telephony testing that accepts connections without any authentication. An unauthenticated remote attacker who can reach an exposed runner endpoint can connect to this endpoint, send a crafted Twilio handshake message containing an attacker-supplied callSid, and cause the server to issue an authenticated Twilio REST API hang-up request against that call SID using the server operator's own credentials. This may allow the attacker to forcibly terminate an active call on the victim's Twilio account if the attacker knows or obtains a valid call SID for that account. Equivalent unauthenticated call-control sinks exist for Telnyx and Plivo. Maintainers are evaluating the final CVSS 3.1 score.

Details

The pipecat development runner registers a WebSocket route at /ws (src/pipecat/runner/run.py:1116). When a client connects, the server immediately accepts the connection without performing any authentication or signature verification (run.py:1119):

await websocket.accept()   # run.py:1119 — no auth check before this point

After acceptance, the server reads the Twilio WebSocket stream-start handshake and extracts the callSid field verbatim from the attacker-controlled JSON payload (src/pipecat/runner/utils.py:223):

call_id: start_data.get("callSid")   # utils.py:223 — tainted, attacker-supplied

The tainted call_id is then passed directly into TwilioFrameSerializer alongside the server's own Twilio account credentials, which are read from environment variables (src/pipecat/runner/utils.py:513-517):

TwilioFrameSerializer(
    stream_sid=stream_id,
    call_sid=call_id,                          # TAINTED
    account_sid=os.getenv("TWILIO_ACCOUNT_SID"),  # server credential
    auth_token=os.getenv("TWILIO_AUTH_TOKEN"),     # server credential
)

TwilioFrameSerializer has auto_hang_up defaulting to True (src/pipecat/serializers/twilio.py:56). When the pipeline terminates and serializes an EndFrame or CancelFrame, _hang_up_call() is triggered (twilio.py:141-147). This method constructs a Twilio REST API URL containing the attacker-supplied call_sid and POSTs to it using the server's own credentials (twilio.py:196, twilio.py:206):

POST https://api.twilio.com/2010-04-01/Accounts/{account_sid}/Calls/{attacker_call_sid}.json
Authorization: Basic <base64(account_sid:auth_token)>
Body: Status=completed

The same unauthenticated call-control pattern exists for Telnyx (src/pipecat/serializers/telnyx.py:188, :195) and Plivo (src/pipecat/serializers/plivo.py:180, :187).

Although the runner defaults to localhost and is documented as a development runner, its telephony mode is commonly used with a public proxy hostname so that telephony providers can connect inbound calls. If the development runner is exposed to untrusted networks while configured with Twilio, Telnyx, or Plivo credentials, this becomes a realistic network-reachable attack surface.

PoC

Prerequisites

  • Docker (for building the isolated PoC image)
  • A clone of the pipecat repository at commit b982b45a7ae1e5ee99e4390ad5a116cdd9b4a8e2 placed at <context_root>/repo/
  • The files vuln-001/Dockerfile and vuln-001/poc.py present under <context_root>/

Step 1 — Build the Docker image

docker build \
  -f vuln-001/Dockerfile \
  -t vuln001-poc \
  reports/pypiAi_247_pipecat-ai__pipecat

The Dockerfile installs pipecat from the local repository clone, generates a self-signed TLS CA and server certificate for api.twilio.com, and registers that CA in the system trust store so that pipecat's aiohttp-based HTTP client accepts the mock server certificate.

Step 2 — Run the PoC

docker run --rm \
  --add-host api.twilio.com:127.0.0.1 \
 …
Record
GHSA-j8cv-x86q-rj85
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:H
Weakness
CWE-862
Updated
2026-11-02
OSVPYSEC-2026-2878 7.5

Pipecat: Telephony WebSocket `/ws` Unauthenticated Call-Control Abuse via Attacker-Supplied Call SID

Development Runner Telephony WebSocket /ws Unauthenticated Call-Control Abuse via Attacker-Supplied Call SID

Summary

The pipecat development runner registers a /ws WebSocket endpoint for telephony testing that accepts connections without any authentication. An unauthenticated remote attacker who can reach an exposed runner endpoint can connect to this endpoint, send a crafted Twilio handshake message containing an attacker-supplied callSid, and cause the server to issue an authenticated Twilio REST API hang-up request against that call SID using the server operator's own credentials. This may allow the attacker to forcibly terminate an active call on the victim's Twilio account if the attacker knows or obtains a valid call SID for that account. Equivalent unauthenticated call-control sinks exist for Telnyx and Plivo. Maintainers are evaluating the final CVSS 3.1 score.

Details

The pipecat development runner registers a WebSocket route at /ws (src/pipecat/runner/run.py:1116). When a client connects, the server immediately accepts the connection without performing any authentication or signature verification (run.py:1119):

await websocket.accept()   # run.py:1119 — no auth check before this point

After acceptance, the server reads the Twilio WebSocket stream-start handshake and extracts the callSid field verbatim from the attacker-controlled JSON payload (src/pipecat/runner/utils.py:223):

call_id: start_data.get("callSid")   # utils.py:223 — tainted, attacker-supplied

The tainted call_id is then passed directly into TwilioFrameSerializer alongside the server's own Twilio account credentials, which are read from environment variables (src/pipecat/runner/utils.py:513-517):

TwilioFrameSerializer(
    stream_sid=stream_id,
    call_sid=call_id,                          # TAINTED
    account_sid=os.getenv("TWILIO_ACCOUNT_SID"),  # server credential
    auth_token=os.getenv("TWILIO_AUTH_TOKEN"),     # server credential
)

TwilioFrameSerializer has auto_hang_up defaulting to True (src/pipecat/serializers/twilio.py:56). When the pipeline terminates and serializes an EndFrame or CancelFrame, _hang_up_call() is triggered (twilio.py:141-147). This method constructs a Twilio REST API URL containing the attacker-supplied call_sid and POSTs to it using the server's own credentials (twilio.py:196, twilio.py:206):

POST https://api.twilio.com/2010-04-01/Accounts/{account_sid}/Calls/{attacker_call_sid}.json
Authorization: Basic <base64(account_sid:auth_token)>
Body: Status=completed

The same unauthenticated call-control pattern exists for Telnyx (src/pipecat/serializers/telnyx.py:188, :195) and Plivo (src/pipecat/serializers/plivo.py:180, :187).

Although the runner defaults to localhost and is documented as a development runner, its telephony mode is commonly used with a public proxy hostname so that telephony providers can connect inbound calls. If the development runner is exposed to untrusted networks while configured with Twilio, Telnyx, or Plivo credentials, this becomes a realistic network-reachable attack surface.

PoC

Prerequisites

  • Docker (for building the isolated PoC image)
  • A clone of the pipecat repository at commit b982b45a7ae1e5ee99e4390ad5a116cdd9b4a8e2 placed at <context_root>/repo/
  • The files vuln-001/Dockerfile and vuln-001/poc.py present under <context_root>/

Step 1 — Build the Docker image

docker build \
  -f vuln-001/Dockerfile \
  -t vuln001-poc \
  reports/pypiAi_247_pipecat-ai__pipecat

The Dockerfile installs pipecat from the local repository clone, generates a self-signed TLS CA and server certificate for api.twilio.com, and registers that CA in the system trust store so that pipecat's aiohttp-based HTTP client accepts the mock server certificate.

Step 2 — Run the PoC

docker run --rm \
  --add-host api.twilio.com:127.0.0.1 \
 …
Record
PYSEC-2026-2878
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:L/A:H
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
pipecat-ai
PyPI
0.0.77 up to 1.4.0
1.4.0
pipecat-ai
PyPI
0.0.77 up to 1.4.0, plus listed versions
0.0.1000.0.1010.0.1020.0.1030.0.104
Show 31 moreShow less
0.0.1050.0.1060.0.1070.0.1080.0.780.0.790.0.800.0.810.0.820.0.830.0.840.0.850.0.860.0.870.0.880.0.890.0.900.0.910.0.920.0.930.0.940.0.950.0.960.0.970.0.980.0.991.0.01.1.01.2.01.2.11.3.0
1.4.0

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-54695 is a high vulnerability (CVSS 7.5) in Pipecat, published June 18, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.56%, the 47th percentile. Fixed in pipecat-ai 1.4.0.

References

Show 4 moreShow less
This page doesn't list everything

Left out here: the rest of 3 source descriptions. The JSON record has them.

MoveEnter Open