From b848ce2c79bfff4c0d470113085cf1ec45aa8877 Mon Sep 17 00:00:00 2001 From: Teknium Date: Thu, 23 Apr 2026 14:05:15 -0700 Subject: [PATCH] test: cover absolute paths in project env/config approval regex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The original regex only matched relative paths (./foo/.env or bare .env), so the exact command from the bug report — `cp /opt/data/.env.local /opt/data/.env` — did not trigger approval. Broaden the leading-path prefix to accept an absolute leading slash alongside ./ and ../, and add regressions for the bug-report command and its redirection variant. --- tests/tools/test_approval.py | 18 ++++++++++++++++++ tools/approval.py | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/tests/tools/test_approval.py b/tests/tools/test_approval.py index a752b68d7..476fd0d32 100644 --- a/tests/tools/test_approval.py +++ b/tests/tools/test_approval.py @@ -460,6 +460,24 @@ class TestProjectSensitiveCopyPattern: assert key is not None assert "project env/config" in desc.lower() + def test_cp_absolute_path_to_dotenv_requires_approval(self): + # Regression: the real-world bug report was `cp /opt/data/.env.local /opt/data/.env`. + # The regex must cover absolute paths, not just `./` / bare relative paths. + dangerous, key, desc = detect_dangerous_command( + "cp /opt/data/.env.local /opt/data/.env" + ) + assert dangerous is True + assert key is not None + assert "project env/config" in desc.lower() + + def test_redirect_absolute_path_to_dotenv_requires_approval(self): + dangerous, key, desc = detect_dangerous_command( + "cat /opt/data/.env.local > /opt/data/.env" + ) + assert dangerous is True + assert key is not None + assert "project env/config" in desc.lower() + def test_mv_to_nested_config_yaml_requires_approval(self): dangerous, key, desc = detect_dangerous_command("mv tmp/generated.yaml config/config.yaml") assert dangerous is True diff --git a/tools/approval.py b/tools/approval.py index d88b3e877..258f66b6e 100644 --- a/tools/approval.py +++ b/tools/approval.py @@ -63,8 +63,8 @@ _HERMES_ENV_PATH = ( r'(?:\$hermes_home|\$\{hermes_home\})/)' r'\.env\b' ) -_PROJECT_ENV_PATH = r'(?:(?:\.{1,2}/)?(?:[^\s/"\'`]+/)*\.env(?:\.[^/\s"\'`]+)*)' -_PROJECT_CONFIG_PATH = r'(?:(?:\.{1,2}/)?(?:[^\s/"\'`]+/)*config\.yaml)' +_PROJECT_ENV_PATH = r'(?:(?:/|\.{1,2}/)?(?:[^\s/"\'`]+/)*\.env(?:\.[^/\s"\'`]+)*)' +_PROJECT_CONFIG_PATH = r'(?:(?:/|\.{1,2}/)?(?:[^\s/"\'`]+/)*config\.yaml)' _SENSITIVE_WRITE_TARGET = ( r'(?:/etc/|/dev/sd|' rf'{_SSH_SENSITIVE_PATH}|'