From 8a0daf506c570261135a76067b83116306e4d699 Mon Sep 17 00:00:00 2001 From: Lucas Wang Date: Mon, 23 Mar 2026 23:14:21 +0800 Subject: [PATCH 1/2] fix: redact GitHub token from git clone error messages When git clone fails, git may echo the clone URL in stderr. Since the GitHub token is embedded in the URL, it appears in the error message which is logged and saved to the JSON result file. In CI/CD environments this means the token is exposed in workflow logs visible to all repository collaborators (or publicly for public repos). Redact the token from stderr before including it in error messages. --- claudecode/evals/eval_engine.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/claudecode/evals/eval_engine.py b/claudecode/evals/eval_engine.py index 6aff158..c69b601 100644 --- a/claudecode/evals/eval_engine.py +++ b/claudecode/evals/eval_engine.py @@ -235,12 +235,19 @@ def _setup_repository(self, test_case: EvalCase) -> Tuple[bool, str, str]: clone_url = f"https://github.com/{repo_name}.git" if self.github_token: clone_url = f"https://{self.github_token}@github.com/{repo_name}.git" - + try: subprocess.run(['git', 'clone', '--filter=blob:none', clone_url, base_repo_path], check=True, capture_output=True, timeout=TIMEOUT_CLONE) except subprocess.CalledProcessError as e: - error_msg = f"Failed to clone repository: {e.stderr.decode()}" + stderr = e.stderr.decode() if e.stderr else "" + # Redact the GitHub token from git's error output. + # Git may echo the clone URL (which embeds the token) + # in stderr when the clone fails, leaking the credential + # into logs and the JSON result file on disk. + if self.github_token: + stderr = stderr.replace(self.github_token, "[REDACTED]") + error_msg = f"Failed to clone repository: {stderr}" self.log(error_msg) return False, "", error_msg From b8046b742162f1af5ba4c88d07738348122ef3b7 Mon Sep 17 00:00:00 2001 From: Lucas Wang Date: Mon, 23 Mar 2026 23:38:19 +0800 Subject: [PATCH 2/2] fix: use errors='replace' in stderr decode to prevent UnicodeDecodeError Co-Authored-By: Claude Opus 4.6 (1M context) --- claudecode/evals/eval_engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/claudecode/evals/eval_engine.py b/claudecode/evals/eval_engine.py index c69b601..b627014 100644 --- a/claudecode/evals/eval_engine.py +++ b/claudecode/evals/eval_engine.py @@ -240,7 +240,7 @@ def _setup_repository(self, test_case: EvalCase) -> Tuple[bool, str, str]: subprocess.run(['git', 'clone', '--filter=blob:none', clone_url, base_repo_path], check=True, capture_output=True, timeout=TIMEOUT_CLONE) except subprocess.CalledProcessError as e: - stderr = e.stderr.decode() if e.stderr else "" + stderr = e.stderr.decode(errors='replace') if e.stderr else "" # Redact the GitHub token from git's error output. # Git may echo the clone URL (which embeds the token) # in stderr when the clone fails, leaking the credential