From eaf7acd37263ec9ede92878d541c0fd8730370f5 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 25 Sep 2026 22:26:32 +0000 Subject: [PATCH] Fix missing timeout in check_test_framework.py to prevent DoS. Co-authored-by: wryenmeek <6856065+wryenmeek@users.noreply.github.com> --- .jules/sentinel.md | 5 +++++ scripts/hooks/check_test_framework.py | 18 +++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.jules/sentinel.md b/.jules/sentinel.md index 438b6345..4d193ee8 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -67,3 +67,8 @@ **Vulnerability:** External CLI executions (`subprocess.run`) in hook scripts like `check_cross_functional_review.py` did not explicitly define a `timeout`, risking unbounded hangs and DoS if the external command stalls. **Learning:** `subprocess.run` by default has no timeout, making scripts vulnerable to infinite waits. **Prevention:** Always explicitly define a `timeout` argument (e.g., `timeout=15`) in `subprocess.run` and catch `subprocess.TimeoutExpired` to fail securely. + +## 2024-10-29 - [Missing Subprocess Timeout in check_test_framework.py] +**Vulnerability:** External CLI executions (`subprocess.run`) in `scripts/hooks/check_test_framework.py` did not explicitly define a `timeout`, risking unbounded hangs and DoS if the external command stalls. +**Learning:** `subprocess.run` by default has no timeout, making scripts vulnerable to infinite waits. +**Prevention:** Always explicitly define a `timeout` argument (e.g., `timeout=15`) in `subprocess.run` and catch `subprocess.TimeoutExpired` to fail securely. diff --git a/scripts/hooks/check_test_framework.py b/scripts/hooks/check_test_framework.py index 42ae4b2c..7fb226a8 100755 --- a/scripts/hooks/check_test_framework.py +++ b/scripts/hooks/check_test_framework.py @@ -41,13 +41,17 @@ class StagedTestPath: def _run_git(*args: str) -> tuple[int, str, str]: - result = subprocess.run( - ["git", *args], - capture_output=True, - text=True, - check=False, - ) - return result.returncode, result.stdout, redact_stderr(result.stderr or "") + try: + result = subprocess.run( + ["git", *args], + capture_output=True, + text=True, + check=False, + timeout=15, + ) + return result.returncode, result.stdout, redact_stderr(result.stderr or "") + except subprocess.TimeoutExpired: + return 1, "", "git command timed out" def _normalize_path(path: str) -> str: