From 3781d602a172880d06b707b99046cd1c21f21fbd Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Tue, 30 Jun 2026 11:34:37 +1000 Subject: [PATCH] Fix overenthusiastic match on pass --- enroll/ignore.py | 27 ++++++++++++++------------- tests/test_secret_detection.py | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/enroll/ignore.py b/enroll/ignore.py index 416b5ba..2bc75ea 100644 --- a/enroll/ignore.py +++ b/enroll/ignore.py @@ -103,23 +103,24 @@ HIGH_CONFIDENCE_SECRET_PATTERNS = [ # framing, so it is scanned on raw bytes. re.compile( rb"""(?ix) - (^|[^A-Za-z0-9]) + (^|[^A-Za-z0-9_.-]) [\"']? ( - [A-Za-z0-9_.-]* + (?:[A-Za-z0-9]+[_.-])* ( - password|passwd|passphrase|pass|pin|pwd| - token|auth[_-]?token|access[_-]?token|refresh[_-]?token| - secret|client[_-]?secret|secret[_-]?key| - api[_-]?key|access[_-]?key|private[_-]?key| + password|passwd|passphrase|pwd| + token|auth[_.-]?token|access[_.-]?token|refresh[_.-]?token| + secret|client[_.-]?secret|secret[_.-]?key| + api[_.-]?key|access[_.-]?key|private[_.-]?key| credential|credentials| - aws[_-]?access[_-]?key[_-]?id|aws[_-]?secret[_-]?access[_-]?key| - azure[_-]?client[_-]?secret|azure[_-]?tenant[_-]?id|azure[_-]?client[_-]?id| - google[_-]?application[_-]?credentials|gcp[_-]?service[_-]?account| - service[_-]?account[_-]?key| - session_key + aws[_.-]?access[_.-]?key[_.-]?id|aws[_.-]?secret[_.-]?access[_.-]?key| + azure[_.-]?client[_.-]?secret|azure[_.-]?tenant[_.-]?id|azure[_.-]?client[_.-]?id| + google[_.-]?application[_.-]?credentials|gcp[_.-]?service[_.-]?account| + service[_.-]?account[_.-]?key| + session[_.-]?key| + pass|pin ) - [A-Za-z0-9_.-]* + (?:[_.-][A-Za-z0-9]+)* ) [\"']? \s*[:=] @@ -141,7 +142,7 @@ SENSITIVE_CONTENT_PATTERNS = [ # heuristic and the only one tolerated inside comments, because stock config # files legitimately ship value-less commented hints (e.g. "# token"). re.compile( - rb"(?i)\b(pass|passwd|password|passphrase|token|secret|" + rb"(?i)\b(pass|pin|passwd|password|passphrase|token|secret|" rb"credentials?|api[_-]?key)\b" ), ] diff --git a/tests/test_secret_detection.py b/tests/test_secret_detection.py index 7cdb81b..4b37896 100644 --- a/tests/test_secret_detection.py +++ b/tests/test_secret_detection.py @@ -51,6 +51,7 @@ def test_bare_word_password_denied(): b"machine api.example.com login bob password s3cret\n", b"passphrase mysecretphrase\n", b"credentials /run/creds/db\n", + b"pin 1234\n", ]: assert ( pol._content_deny_reason("/etc/svc.conf", data) == "sensitive_content" @@ -63,11 +64,29 @@ def test_ppp_secrets_paths_denied(): assert pol._path_deny_reason(p) == "denied_path", p +def test_short_credential_key_components_denied(): + pol = IgnorePolicy(dangerous=False) + for data in [ + b"pass = hunter2\n", + b"db_pass = hunter2\n", + b"pass_key = hunter2\n", + b"db-pass: hunter2\n", + b"pin = 1234\n", + b"db_pin = 1234\n", + b"pin-key: 1234\n", + ]: + assert ( + pol._content_deny_reason("/etc/app.conf", data) == "sensitive_content" + ), data + + def test_password_keyword_no_false_positives(): pol = IgnorePolicy(dangerous=False) for data in [ b"passive_mode = true\n", b"PassengerRoot /usr/lib\n", + b"pinboard = enabled\n", + b"pinot_region = noir\n", b"description = reset the account\n", b"compression = gzip\n", ]: