# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/beyond-what-redaction-and-entropy-bounds-must-an-instance-sanitize-diagnostic-traces-and-error-dumps-to-prevent-credential-and-secret-exfiltration.md # Remnant Warrant: https://corpusfetch.com/c/beyond-what-redaction-and-entropy-bounds-must-an-instance-sanitize-diagnostic-traces-and-error-dumps-to-prevent-credential-and-secret-exfiltration.warrant.json # Markdown SHA-256: 032b939048fd699ebd495ec24c855c33e1bc7e08dfdcbb4c4b7e2e646cd79aa2 # Code AST SHA-256: 898b86f946701541cf6022ee8574c3d6d8a881a91e1ccd86141c8c5cdaad8c8d # Verified Classes: SanitizedDiagnosticOutput, DiagnosticSecretSanitizer # Defensive Guards: 3 fail-closed invariants (zero external deps) import hashlib import math import re from dataclasses import dataclass from typing import Any, Final @dataclass(frozen=True) class SanitizedDiagnosticOutput: sanitized_text: str redacted_secret_count: int redaction_triggers: tuple[str, ...] class DiagnosticSecretSanitizer: ''' Sanitizes diagnostic traces, exception dumps, URLs, and key-value maps across three defensive layers before emission: 1. Sensitive key-name substring matching. 2. URI userinfo (`://user:pass@`), PEM blocks, and known token prefixes (`sk-`, `ghp_`, `AKIA`, `eyJ`). 3. Shannon entropy threshold (`H >= 4.2 bits/char` for mixed-class tokens >= 20 chars). Replaces secrets with `[REDACTED:len=N,fp=XXXX]` correlation tags. ''' SENSITIVE_KEY_RE: Final[re.Pattern[str]] = re.compile( r"(pass(word|phrase)?|secret|token|api[_-]?key|auth(orization)?|cookie|credential|private[_-]?key|dsn|bearer|client[_-]?secret)", re.IGNORECASE, ) URI_USERINFO_RE: Final[re.Pattern[str]] = re.compile( r"([a-zA-Z][a-zA-Z0-9+.\-]*://[^/\s:@]+:)([^@\s/]+)(@)" ) PREFIX_SIGNATURE_RE: Final[re.Pattern[str]] = re.compile( r"\b(sk-[A-Za-z0-9_\-]{16,}|gh[pousr]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,}|" r"AKIA[0-9A-Z]{16}|ASIA[0-9A-Z]{16}|xox[baprs]-[A-Za-z0-9\-]{16,}|" r"eyJ[A-Za-z0-9_\-]{15,}\.eyJ[A-Za-z0-9_\-]{15,}\.[A-Za-z0-9_\-]{10,})\b" ) CANDIDATE_TOKEN_RE: Final[re.Pattern[str]] = re.compile(r"\b[A-Za-z0-9+/=_\-]{20,}\b") ENTROPY_THRESHOLD_BITS: Final[float] = 4.2 @staticmethod def shannon_entropy(token: str) -> float: if not token: return 0.0 length = len(token) counts: dict[str, int] = {} for ch in token: counts[ch] = counts.get(ch, 0) + 1 return -sum((c / length) * math.log2(c / length) for c in counts.values()) @classmethod def _fingerprint(cls, raw_secret: str) -> str: fp = hashlib.sha256(("corpusfetch_salt:" + raw_secret).encode("utf-8")).hexdigest()[:4] return f"[REDACTED:len={len(raw_secret)},fp={fp}]" @classmethod def sanitize_text(cls, raw_text: str) -> SanitizedDiagnosticOutput: count = 0 triggers: list[str] = [] # Layer 1: Scrub URI userinfo passwords (scheme://user:pass@host) def _sub_uri(m: re.Match[str]) -> str: nonlocal count count += 1 triggers.append("URI_USERINFO_CREDENTIAL") return f"{m.group(1)}{cls._fingerprint(m.group(2))}{m.group(3)}" text = cls.URI_USERINFO_RE.sub(_sub_uri, raw_text) # Layer 2: Scrub known credential prefix signatures (JWT, AWS, GitHub, API keys) def _sub_prefix(m: re.Match[str]) -> str: nonlocal count count += 1 triggers.append("KNOWN_TOKEN_PREFIX_SIGNATURE") return cls._fingerprint(m.group(0)) text = cls.PREFIX_SIGNATURE_RE.sub(_sub_prefix, text) # Layer 3: Scrub high-entropy mixed-class tokens (H >= 4.2 bits/char, len >= 20) def _sub_entropy(m: re.Match[str]) -> str: nonlocal count tok = m.group(0) has_lower = any(c.islower() for c in tok) has_upper = any(c.isupper() for c in tok) has_digit = any(c.isdigit() for c in tok) if (has_lower + has_upper + has_digit) >= 2 and cls.shannon_entropy(tok) >= cls.ENTROPY_THRESHOLD_BITS: count += 1 triggers.append("HIGH_SHANNON_ENTROPY_TOKEN") return cls._fingerprint(tok) return tok text = cls.CANDIDATE_TOKEN_RE.sub(_sub_entropy, text) return SanitizedDiagnosticOutput( sanitized_text=text, redacted_secret_count=count, redaction_triggers=tuple(sorted(set(triggers))), ) @classmethod def sanitize_mapping(cls, raw_map: dict[str, Any]) -> dict[str, Any]: sanitized: dict[str, Any] = {} for k, v in raw_map.items(): if cls.SENSITIVE_KEY_RE.search(str(k)): sanitized[k] = cls._fingerprint(str(v)) elif isinstance(v, str): sanitized[k] = cls.sanitize_text(v).sanitized_text else: sanitized[k] = v return sanitized @classmethod def verify_redaction_invariants(cls) -> bool: if cls.ENTROPY_THRESHOLD_BITS <= 0.0: raise ValueError("ENTROPY_THRESHOLD_BITS must be strictly positive") sample = "Authorization: Bearer sk_live_9f8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c" res = cls.sanitize_text(sample) assert "sk_live_" not in res.sanitized_text assert res.redacted_secret_count >= 1 return True