Spaces:
Sleeping
Sleeping
File size: 2,376 Bytes
2e658e7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | #!/usr/bin/env python3
"""Fail-closed repository secret scan with explicit fixture exclusions."""
from __future__ import annotations
import argparse
import os
import re
import sys
from pathlib import Path
PATTERNS = (
re.compile(r"-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----"),
re.compile(
r"\b(?i:api[_-]?key|api[_-]?secret|access[_-]?token|password)"
r"\s*[:=]\s*['\"]?"
r"(?!(?:[A-Z][A-Z0-9_]{7,}\b|example\b|placeholder\b|redacted\b|test\b))"
r"[A-Za-z0-9_./+\-=]{16,}"
),
re.compile(r"\b(?:hf_|sk-|xox[baprs]-)[A-Za-z0-9_-]{24,}\b"),
)
SKIP_DIRS = {".git", ".pytest_cache", "__pycache__", ".venv", "node_modules"}
SKIP_SUFFIXES = {".png", ".jpg", ".jpeg", ".gif", ".webp", ".zip", ".gz", ".pyc", ".sqlite3"}
FIXTURE_PREFIXES = {"hermes_overlay/tests/", "scripts/ci_secret_scan.py", "scripts/backup_allowlist.py", "scripts/verify_required_failures.py"}
def scan(root: Path, *, allow_fixtures: bool) -> list[str]:
findings: list[str] = []
for path in root.rglob("*"):
if not path.is_file() or any(part in SKIP_DIRS for part in path.parts) or path.suffix.lower() in SKIP_SUFFIXES:
continue
rel = path.relative_to(root).as_posix()
if allow_fixtures and any(rel.startswith(prefix) for prefix in FIXTURE_PREFIXES):
continue
if path.name.startswith(".env") and path.name != ".env.example":
findings.append(f"denied secret filename: {rel}")
continue
try:
text = path.read_text(encoding="utf-8", errors="ignore")[:512_000]
except OSError:
continue
for pattern in PATTERNS:
if pattern.search(text):
findings.append(f"secret-like content: {rel}")
break
return findings
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("path", nargs="?", default=str(Path(__file__).resolve().parents[1]))
parser.add_argument("--no-fixture-exclusions", action="store_true")
args = parser.parse_args()
root = Path(args.path).resolve()
findings = scan(root, allow_fixtures=not args.no_fixture_exclusions)
for finding in findings:
print(f"ERROR: {finding}")
print(f"secret_scan_findings={len(findings)}")
return 1 if findings else 0
if __name__ == "__main__":
raise SystemExit(main())
|