Submit #1013214: speaches-ai Speaches git master 2026-04-18 (commit 993994f) Unsafe Reflectioninfo

Titlespeaches-ai Speaches git master 2026-04-18 (commit 993994f) Unsafe Reflection
DescriptionA vulnerability was found in Speaches git commit 993994f7984bf3fe9655b267448328cf66fccb42 and classified as critical 9.8. Affected is the PyannoteDiarizationModelManager._load_fn function of the pyannote diarization model loading component (src/speaches/executors/pyannote_diarization.py), reached through the unauthenticated POST /v1/audio/diarization endpoint. The manipulation of the argument model leads to unsafe reflection (CWE-470): the model ID is selected by attacker-written model card metadata and passed to pyannote.audio Pipeline.from_pretrained(), which resolves the config.yaml pipeline.name field through get_class_by_name() without a module allowlist and invokes the resolved installed callable with the expanded params mapping. It is possible to launch the attack remotely. A model repository containing no program files (only README.md, config.yaml and a text marker) makes the server process invoke any installed callable with attacker-chosen arguments; the demonstrated payload huggingface_hub.snapshot_download with params.repo_id=victim/second-stage causes a server-side second-stage request for an attacker-chosen repository. pyannote.audio >= 4 injects token/cache_dir keyword arguments into the params, filtering strict-signature payloads such as subprocess.call (confirmed TypeError in reproduction), while kwargs-tolerant callables remain fully attacker-controlled and pyannote 3.x-era loaders do not inject these keywords. Technical Details - Affected file/function: src/speaches/executors/pyannote_diarization.py / PyannoteDiarizationModelManager._load_fn (lines 75-85), via src/speaches/routers/diarization.py (POST /v1/audio/diarization) - Vulnerable parameter: model (model ID of the diarization request, routed solely by model card metadata) - Attack vector: Network - Privileges required: None (endpoint unauthenticated in the default configuration) - Trigger condition: a repository whose metadata passes the diarization filter (pipeline_tag speaker-diarization, tag pyannote) is present in the local HuggingFace cache, then a single unauthenticated diarization request with that model ID resolves pipeline.name and invokes the selected callable Impact - Confidentiality: High (code execution in the server process exposes all data accessible to it) - Integrity: High (attacker-chosen callable invocation permits arbitrary state changes and server-side requests) - Availability: High (the invoked object can crash or monopolize the server process) CVSS v3.1 Score: 9.8 (Critical) Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H Timeline - Discovered: 2026-10-04 - Vendor notified: [pending] - Patch released: [pending] - Public disclosure: [pending] Countermeasure Enforce the AVAILABLE_MODELS allowlist (currently only applied to the listing/download endpoints) inside the load path before calling Pipeline.from_pretrained(), and stop relying on pyannote's config-driven reflection for untrusted repositories by instantiating the diarization pipeline class directly or validating config.yaml pipeline.name against a strict allowlist.
Source⚠️ https://github.com/speaches-ai/speaches/issues/679
User
 Dem0000000 (UID 98743)
Submission10/04/2026 17:58 (15 days ago)
Moderation10/19/2026 07:26 (15 days later)
StatusAccepted
VulDB entry422250 [speaches-ai speaches up to 0.9.0-rc.3 Pyannote Diarization Model Loading pyannote_diarization.py PyannoteDiarizationModelManager._load_fn model externally-controlled input to select classes or code]
Points20

Do you want to use VulDB in your project?

Use the official API to access entries easily!