From 89f0a2508248d55691203b540a96bb23e4ebe49d Mon Sep 17 00:00:00 2001 From: Palash Debnath <4178343+debpalash@users.noreply.github.com> Date: Wed, 2 Sep 2026 06:13:11 +0530 Subject: [PATCH] fix(mcp): bound encoded audio before decode --- backend/mcp_server.py | 8 ++++++++ tests/test_mcp_output_mode.py | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/backend/mcp_server.py b/backend/mcp_server.py index 258e8a31..55d9b94b 100644 --- a/backend/mcp_server.py +++ b/backend/mcp_server.py @@ -240,6 +240,14 @@ def _read_input_audio( if not raw: return None, f"{label} is empty" return raw, None + encoded = ( + audio_base64.split(",", 1)[-1] + if audio_base64.startswith("data:") + else audio_base64 + ) + max_encoded_bytes = 4 * ((_MAX_INPUT_BYTES + 2) // 3) + if len(encoded) > max_encoded_bytes: + return None, too_big raw = _decode_ref_audio(audio_base64) if raw is None: return None, f"{label} is not valid base64" diff --git a/tests/test_mcp_output_mode.py b/tests/test_mcp_output_mode.py index 64e871c7..34f15108 100644 --- a/tests/test_mcp_output_mode.py +++ b/tests/test_mcp_output_mode.py @@ -126,6 +126,20 @@ def test_base64_limit_applies_to_decoded_bytes(monkeypatch): assert raw is None and err == "audio exceeds 200 MB limit" +def test_oversized_base64_is_rejected_before_decode(monkeypatch): + import mcp_server + + monkeypatch.setattr(mcp_server, "_MAX_INPUT_BYTES", 3) + + def fail_decode(_value): # pragma: no cover - must short-circuit first + raise AssertionError("oversized base64 reached the decoder") + + monkeypatch.setattr(mcp_server, "_decode_ref_audio", fail_decode) + oversized = base64.b64encode(b"abcd").decode() + raw, err = mcp_server._read_input_audio(oversized, None) + assert raw is None and err == "audio exceeds 200 MB limit" + + def test_concurrent_parent_replacement_cannot_escape_base( monkeypatch, tmp_path ):