Skip to content

gitleaks: no default rule covers hex-encoded generic high-entropy secrets #348

Description

@davidmatousek

Gap detail

Found by the empirical rule-ID probe for Feature 281 / Issue #285 (T010/T012).

Method: Scanned 6 canonical secret-pattern fixtures against gitleaks v8.30.1's default ruleset only ([extend] useDefault = true, no tachi-specific allow-lists), using gitleaks dir <fixtures> --config=<default-only-probe.toml> --report-format=json.

Result: 5 of 6 canonical patterns are covered by an active default rule. Pattern 6 (generic high-entropy string) is not covered when the secret uses a hex-only alphabet.

Pattern Fixture alphabet Active default RuleID Fired
GitHub PAT n/a github-pat yes
AWS access key n/a aws-access-token yes
OpenAI key base62-ish generic-api-key (not openai-api-key) yes
Anthropic key n/a anthropic-api-key yes
PEM private-key block n/a private-key yes
Generic high-entropy string hex only (openssl rand -hex 24, 48 chars) (none) no

Root cause (isolated via 3 follow-up variants):

  • A 48-char hex-alphabet secret (generic_secret = "d7de6a92...d9a7") produces zero findings under the default ruleset, regardless of variable name (tested generic_secret and api_key).
  • The same secret length, re-encoded to a base62 alphabet (mixed-case + digits, e.g. Xk9mQ2vR7pLwT4nJ8hG3fD6sB1cA5zY0uO), does fire generic-api-key — again regardless of variable name.
  • Conclusion: the blocker is alphabet size / Shannon entropy-per-character, not string length or key-name adjacency. Gitleaks' default generic-api-key rule has an entropy floor that a hex-only alphabet (16 symbols, ~4 bits/char) can fall below even at generous lengths, while a base62 alphabet (62 symbols, ~5.95 bits/char) clears it at the same length.

Why this matters: hex-encoded tokens are a common real-world secret format (many openssl rand -hex-style API keys, session tokens, and internal service credentials use hex), so this is not a synthetic edge case — it's a realistic blind spot in gitleaks' default coverage.

Secondary finding (not a gap, but worth recording): the OpenAI key fixture fires under generic-api-key, not the dedicated openai-api-key rule as originally hypothesized in the fixture's own code comment (tests/fixtures/gitleaks-rule-interaction/staged-credential/openai-key.txt). The dedicated rule exists in gitleaks' default config but did not match this fixture's exact format under v8.30.1 — generic-api-key caught it as a fallback. Worth a follow-up look at whether the fixture format needs updating to match the current openai-api-key regex, independent of this hex-entropy gap.

Suggested remediation options (not prescriptive — architect/PM to decide)

  • Add a tachi-specific custom gitleaks rule for hex-alphabet high-entropy strings above a length threshold, layered on top of useDefault = true.
  • Document the gap in docs/standards/PRECOMMIT_HOOKS.md as a known limitation requiring manual review vigilance for hex-format secrets.
  • Track upstream gitleaks issue/PR if one exists for hex-entropy detection improvements.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions