
elenco di pattern regex per token oauth / api con sorgente fornita
Uno scanner con fonti, testato e con verifica offline per token e segreti OAuth / API. Ogni pattern è con fonti (documentazione primaria del provider), testato (campioni positivi + negativi) e verificato (compatibile RE2, controllato per ReDoS). Include una CLI con livelli di affidabilità. La fonte di verità è DATA in build_patterns.py; patterns.json e questo file sono generati da esso.
109 pattern / 64 provider / generato il 2026-07-02
pip install -e . # console script + importable package
regextokens scan PATH... # walk files/dirs, report findings
regextokens scan PATH -m verified # only offline-proven findings
regextokens scan PATH -f sarif # SARIF for GitHub code scanning
regextokens list # show the catalog
Stato di uscita: 0 nessun risultato, 1 risultati al livello richiesto o superiore, 2 errore. Puntalo su un diff o su un albero in CI per bloccare i merge. I segreti sono oscurati nell'output per impostazione predefinita.
Accetta i risultati revisionati (fixture di test, esempi nella documentazione) in modo che la CI fallisca solo su segreti nuovi:
regextokens scan . --write-baseline .regextokens-baseline.json # snapshot current findings
regextokens scan . --baseline .regextokens-baseline.json # subtract them
La baseline memorizza le impronte digitali (sha256 dell'id del pattern + corpo del segreto sottoposto a hash), mai i segreti stessi, quindi è sicuro eseguirne il commit. La corrispondenza è indipendente dalle righe — modificare sopra un risultato accettato non ne annulla la soppressione — ma lo stesso token in un file diverso è una nuova esposizione e viene segnalato. Una sezione allow modificata manualmente contiene la policy: glob di percorso fnmatch e id dei pattern. --write-baseline la preserva e la applica. Questo repository esegue il commit della propria baseline che copre i campioni sintetici in build_patterns.py; la CI esegue l'auto-scansione rispetto ad essa.
# .pre-commit-config.yaml
repos:
- repo: https://github.com/odomojuli/regextokens
rev: v0.2.0
hooks:
- id: regextokens
# .github/workflows/secrets.yml
jobs:
secrets:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: odomojuli/regextokens@main
with:
min-confidence: probable
# baseline: .regextokens-baseline.json
# optional: feed the SARIF to code scanning
# - uses: github/codeql-action/upload-sarif@v3
# if: always()
# with: {sarif_file: regextokens.sarif}
Entrambi impostano per impostazione predefinita -m probable: il livello low include identificatori pubblici e segnaposto che renderebbero inutilizzabile un controllo sui commit.
Ogni risultato viene valutato tramite prova offline — solo calcolo locale, nessuna rete, nessuna chiamata all'emittente. Una corrispondenza di forma risponde alla domanda "questo sembra un token?"; questi controlli rispondono alla domanda "possiamo dimostrare, localmente, che lo è o non lo è?". Filtra con -m/--min-confidence.
verified-offline — un checksum o un decoder dimostra che la struttura è autentica (CRC32 di GitHub/npm; convalidato empiricamente su token revocati reali).probable — struttura più un corpo con entropia di Shannon coerente con un segreto reale.low — solo corrispondenza di forma; potrebbe essere un segnaposto o un identificatore pubblico.rejected — la prova offline indica che questo è dimostrabilmente non un token reale (ad es. CRC32 non corrispondente); scartato prima di arrivare a te.Il livello rejected è l'elemento distintivo: una stringa ghp_/npm_ con prefisso e lunghezza validi ma un checksum errato viene scartata con certezza, eliminando la più ampia classe di falsi positivi per i provider di maggior valore. La prova offline non afferma mai che una chiave sia attiva — per questo serve ancora l'API dell'emittente.
pip install pytest
pytest # validate every pattern + engine
python build_patterns.py # regenerate patterns.json + README.md
Consuma il catalogo direttamente (senza engine):
import json, re
pats = json.load(open("patterns.json"))["patterns"]
rx = {p["id"]: re.compile(p["regex"]) for p in pats}
rx["github-pat-classic"].search(text)
build_patterns.py — fonte di verità (DATA) + validatore; ricostruisce patterns.json e README.md.patterns.json — catalogo generato (leggibile da macchina). Non modificare mai a mano.regextokens/ — pacchetto installabile: catalog (caricamento), scanner (scansione/match), verify (verifica offline), baseline (risultati accettati + allowlist), report (human/JSON/SARIF), cli. Include una copia sincronizzata di patterns.json..pre-commit-hooks.yaml / action.yml / .github/workflows/ — distribuzione: hook pre-commit, GitHub Action composita, CI + rilascio PyPI attivato da tag (trusted publishing).tests/ — test_patterns.py (ogni pattern: compilazione, match, RE2, ReDoS) e test_engine.py (scanner, verify, report, CLI, sincronizzazione catalogo).sniffer-audit.md — audit di altri scanner di segreti (verifica, obsolescenza).references.bib / references.md — bibliografia della letteratura sul rilevamento dei segreti.re di Python. Nessun lookbehind o backreference.re.search (scansione di testo incorporato). Avvolgere con ^/$ per usarli come validatori.\b racchiudono la maggior parte dei token. Rimuoverli se si scansiona all'interno di blob base64.prefix = affidabile da solo; structure = forma fissa; keyword = vincolato a una keyword vicina; identifier = pubblico, non segreto; encoding = controllo di formato, non segreto.patterns.json sono riempitivi sintetici, non credenziali reali.sniffer-audit.md — come i principali scanner costruiscono e verificano i pattern, con dati di benchmark.references.bib / references.md — bibliografia della letteratura sul rilevamento dei segreti.Stringa Base64 [encoding]
^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$
Validatore di formato, non un segreto. Alfabeto Base64 standard con padding. Ancorato.
src: https://datatracker.ietf.org/doc/html/rfc4648#section-4
JSON Web Token (JWT) [structure]
\bey[A-Za-z0-9_-]{10,}\.ey[A-Za-z0-9/_-]{10,}\.[A-Za-z0-9/_-]{10,}
Tre segmenti base64url. L'header inizia con ey (cioè {"). Decodifica per ispezionare; la firma da sola non è il segreto.