From b2a269b0ae703fabc8ce40b7ff5e70656045ea50 Mon Sep 17 00:00:00 2001 From: memosr Date: Mon, 18 May 2026 22:55:37 +0300 Subject: [PATCH] fix(security): strip directory components from Teams recording display_name to prevent path traversal --- plugins/teams_pipeline/pipeline.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/teams_pipeline/pipeline.py b/plugins/teams_pipeline/pipeline.py index d1d1616486146..46142e36a2a41 100644 --- a/plugins/teams_pipeline/pipeline.py +++ b/plugins/teams_pipeline/pipeline.py @@ -458,7 +458,11 @@ async def _transcribe_recording( temp_root = self.config.tmp_dir or (get_hermes_home() / "tmp" / "teams_pipeline") temp_root.mkdir(parents=True, exist_ok=True) with tempfile.TemporaryDirectory(dir=str(temp_root), prefix="teams-recording-") as tmp_dir: - recording_name = recording.display_name or f"{recording.artifact_id}.mp4" + # display_name comes from Graph API and is ultimately set by + # the meeting organizer — strip any directory components so a + # crafted name like "../../etc/cron.d/evil" can't escape tmp_dir. + raw_name = recording.display_name or f"{recording.artifact_id}.mp4" + recording_name = Path(raw_name).name or f"{recording.artifact_id}.mp4" recording_path = Path(tmp_dir) / recording_name await download_recording_artifact( self.graph_client,