keyhog-core 0.5.50

keyhog-core: shared data model and detector specifications for the KeyHog secret scanner
Documentation
# HTTP Basic Authorization credential: `Authorization: Basic <base64>` (or a
# bare `Basic <base64>`), where the base64 blob decodes to `user:password`.
#
# Why this detector:
#   On the Samsung/CredData benchmark the "Auth:Basic Authorization" class is
#   ~600 labeled positives whose value is, 100% of the time, the base64 blob
#   after `Basic `. keyhog caught ~0 of them, there was no header-shaped
#   detector for it. Measured on the full CredData tree (value-overlap scored):
#   `Basic <base64{16+}>` = 643 TP / 15 FP, precision 0.977. A 16+-char
#   contiguous base64 run immediately after the `Basic ` scheme token is the
#   precise, recall-safe anchor; ordinary prose after the word "basic" almost
#   never contains one.
#
# The base64 blob is the credential (it carries `user:password`); the bench
# overlap scorer base64-decodes both sides, so reporting the blob overlaps the
# labeled value regardless of which surface CredData stored.
#
# Verify: no verification endpoint (the protected resource is unknown).

[detector]
id = "basic-auth-credentials"
name = "HTTP Basic Authorization Credentials"
service = "generic"
severity = "high"
ml = { match_mode = "lift", entropy_mode = "disabled", weight = 1.0, context_radius_lines = 5 }
match_confidence = { literal_prefix_weight = 0.35, context_anchor_weight = 0.20, entropy_weight = 0.20, high_entropy_partial_weight = 0.12, moderate_entropy_threshold = 3.0, moderate_entropy_weight = 0.05, low_entropy_penalty_floor = 2.0, low_entropy_min_match_length = 10, low_entropy_penalty_multiplier = 0.60, keyword_nearby_weight = 0.10, sensitive_file_weight = 0.10, companion_weight = 0.05, very_high_entropy_margin = 1.2999999999999998, named_anchor_floor = 0.55, assignment_context_multiplier = 1.0, string_literal_context_multiplier = 0.9, unknown_context_multiplier = 0.8, documentation_context_multiplier = 0.3, comment_context_multiplier = 0.4, test_context_multiplier = 0.3, encrypted_context_multiplier = 0.05, soft_context_suppression_threshold = 0.5, encrypted_context_suppression_threshold = 0.8, post_match = { placeholder_multiplier = 0.05, minimum_byte_diversity = 0.1, low_diversity_multiplier = 0.1, maximum_repeat_ratio = 0.8, degenerate_run_min_length = 10, degenerate_repeat_multiplier = 0.1, fixture_path_multiplier = 0.5, ml_context_reapply_below = 0.95 } }
keywords = ["Basic", "basic"]

[[detector.patterns]]
# `Basic <base64>`: the scheme token, whitespace, then a 16+-char base64 blob
# (optionally `=`-padded). Whole-word `\b` on `Basic` so `basically` does not
# trip it.
regex = '''(?i)\bbasic\s+([A-Za-z0-9+/]{16,}={0,2})'''
description = "base64 credential blob following the Basic auth scheme token"
group = 1

# No verify block (generic detector, protected resource unknown).

[[detector.tests]]
test_positive = "Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l"
test_negative = "Basic auth is required to reach this endpoint."