From b0e7e3c08d41226e2fc1c054ba427e8aba2eb223 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Mon, 6 Jul 2026 07:10:54 +0900 Subject: [PATCH] harden: validate MCP shrink_media inputs (file source, positive target) The MCP tool checked only that the source path exists. A directory source, or target_bytes <= 0, fell through to the engine and surfaced as an opaque "Conversion failed with error: ..." string instead of a clear, actionable message at the trust boundary. - Reject a source that is not a regular file (e.g. a directory). - Reject target_bytes <= 0 up front. Both return a clear "Error: ..." string, consistent with the existing source-not-found handling and the web app's input validation. Tests (+2): directory source rejected, non-positive target rejected. mcp_driver.py stays at 100% coverage; interrogate 100%; full suite 115 tests, no new failures (5 macOS-only xattr errors pre-existing / Linux-green). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01CJRVbDrp1vGYkJgNHMGPpG --- mcp_driver.py | 4 ++++ tests/test_mcp_driver.py | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/mcp_driver.py b/mcp_driver.py index 1c6f621..8aab575 100644 --- a/mcp_driver.py +++ b/mcp_driver.py @@ -24,6 +24,10 @@ def shrink_media(source_path: str, output_dir: str, target_bytes: int = 2_000_00 if not source.exists(): return f"Error: Source file does not exist: {source}" + if not source.is_file(): + return f"Error: Source path is not a file: {source}" + if target_bytes <= 0: + return "Error: target_bytes must be greater than 0." out_dir.mkdir(parents=True, exist_ok=True) root = source.parent diff --git a/tests/test_mcp_driver.py b/tests/test_mcp_driver.py index a0d7e31..6feba91 100644 --- a/tests/test_mcp_driver.py +++ b/tests/test_mcp_driver.py @@ -65,3 +65,21 @@ def test_shrink_media_handles_empty_result(self, mock_convert_file): if __name__ == '__main__': unittest.main() + + +class MCPDriverValidationTests(unittest.TestCase): + """Trust-boundary input validation for the MCP shrink_media tool.""" + + def test_rejects_directory_source(self): + import tempfile + with tempfile.TemporaryDirectory() as temp_dir: + result = shrink_media(temp_dir, temp_dir + "/out") + self.assertIn("is not a file", result) + + def test_rejects_nonpositive_target_bytes(self): + import tempfile + with tempfile.TemporaryDirectory() as temp_dir: + source = Path(temp_dir) / "s.wav" + source.touch() + result = shrink_media(str(source), str(Path(temp_dir) / "out"), 0) + self.assertIn("target_bytes must be greater than 0", result)