
Une skill peut servir de premier filet de sécurité : un audit léger déclenché à la demande, en lecture seule, qui remonte les fautes grossières avant même la CI. Ce guide montre comment écrire une skill d'audit, la faire tourner sur du code volontairement vulnérable, classer les findings avec un cadre reconnu, et surtout reconnaître ce qu'une skill ne remplace pas. Lab vérifié sur lab-claude.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Écrire une skill d'audit de sécurité en lecture seule
- Détecter secrets en dur,
eval/execet injections shell - Classer les findings avec le cadre CWE
- Situer une skill par rapport à un vrai SAST (ses limites)
Prérequis
Section intitulée « Prérequis »- Les bases des skills et la structure avec scripts
lab-claudeopérationnel (lab vérifié en Claude Code v2.1.152)- Notions de sécurité applicative de base (secrets, injection)
Une skill d'audit dans le workflow
Section intitulée « Une skill d'audit dans le workflow »L'intérêt d'une skill d'audit est le shift-left : déplacer la détection au plus tôt, dans la session de développement, sans attendre le pipeline. Trois principes guident son écriture.
Elle est en lecture seule : un audit ne corrige rien tout seul, il signale et propose. Elle est bornée : un périmètre clair (un dossier), des motifs précis, une sortie structurée. Et elle reste honnête sur son rôle : c'est un premier passage, pas une garantie. Le réflexe de moindre privilège s'applique aussi à la skill elle-même, via un allowed-tools restreint à la lecture.
---name: audit-secudescription: Audite les changements en cours pour problèmes de sécurité (secrets, eval/exec, shell=True, validation manquante). Lecture seule.allowed-tools: Read, Grep, Glob, Bash(uv run ruff check:*)---
Tu réalises un audit de sécurité léger sur le code applicatif.
Recherche dans le dossier ciblé (arg 1 ou `app/` par défaut) :1. Secrets en dur : api_key, secret, token, password, BEGIN PRIVATE KEY2. Exécution dynamique : eval(, exec(, compile(, __import__(3. Shell non sûr : subprocess + shell=True, os.system(4. Entrées non validées : handler qui lit le corps brut au lieu d'un modèle5. Ruff bandit : uv run ruff check --select S .
Ne modifie aucun fichier. Propose la correction dans la réponse.Notez le allowed-tools : Read, Grep, Glob et un ruff check en lecture. Aucune écriture, aucun shell large. Une skill d'audit qui demanderait Bash(*) serait elle-même un risque.
Lab : auditer du code vulnérable
Section intitulée « Lab : auditer du code vulnérable »On confronte la skill à un fichier piégé, contenant trois fautes classiques : un secret en dur, un eval sur entrée, et un subprocess avec shell=True construit par concaténation.
# app/legacy_import.py (cible d'audit)API_KEY = "sk-live-3f9a2b7c1d8e4f6a0b2c4d6e8f0a1b2c"
def import_legacy(source: str): return eval(source)
def sync_files(remote: str): return subprocess.run("rsync -a " + remote + " /data", shell=True)Sans nommer la skill, une demande en langage naturel suffit à la déclencher par sa description :
> fais un audit de securite du code applicatif, cherche secrets et executions dangereusesLa skill remonte les trois fautes, classées critiques, avec le risque et le correctif :
### Critique - app/legacy_import.py
1. Secret en dur (app/legacy_import.py:5) Le préfixe sk-live- suggère une clé de production. Révoquer si réelle. Correctif : API_KEY = os.environ["API_KEY"]
2. eval() sur entrée (app/legacy_import.py:10) RCE direct : __import__('os').system('...') possible. Correctif : supprimer, ou ast.literal_eval limité à des littéraux.
3. subprocess shell=True avec concaténation (app/legacy_import.py:15) Injection : remote = "x; rm -rf /data" exécute la 2e commande. Correctif : subprocess.run(["rsync", "-a", remote, "/data"], check=True)Le résultat n'est pas qu'une liste : la skill explique le vecteur (RCE, injection) et propose un correctif concret, ce qu'un simple grep ne fait pas. C'est l'apport de l'agent par-dessus la détection brute.
Classer les findings avec un cadre
Section intitulée « Classer les findings avec un cadre »Une liste de fautes sans vocabulaire commun se discute mal en équipe. Le cadre adapté au code est le CWE (Common Weakness Enumeration), qui nomme chaque type de faiblesse :
| Finding du lab | CWE | Nom |
|---|---|---|
| Secret en dur | CWE-798 | Use of Hard-coded Credentials |
eval() sur entrée | CWE-95 | Eval Injection |
shell=True concaténé | CWE-78 | OS Command Injection |
Demander à la skill d'annoter chaque finding de son CWE rend le rapport actionnable et traçable. Pour la phase détection et réponse (côté SOC, pas revue de code), le cadre de référence est plutôt MITRE ATT&CK, qui décrit les techniques d'attaquants : c'est sur lui que s'appuient les collections de skills de cybersécurité orientées défense. Les deux cadres sont complémentaires : CWE nomme la faiblesse dans le code, ATT&CK nomme le comportement de l'attaquant.
Ce qu'une skill d'audit ne remplace pas
Section intitulée « Ce qu'une skill d'audit ne remplace pas »Point d'honnêteté, le plus important du guide. Une skill d'audit est un filet rapide, pas une garantie. Elle a des angles morts : elle ne suit pas les flux de données entre fonctions, ne raisonne pas sur tout le graphe d'appel, et peut manquer une injection indirecte comme inventer un faux positif.
Elle ne remplace donc pas un vrai SAST (analyse statique dédiée) comme Bandit, Semgrep ou CodeQL, ni un scan de dépendances, ni les tests de sécurité du pipeline DevSecOps. La bonne place d'une skill d'audit est en amont : un premier tri pendant que vous codez, qui réduit le bruit avant que les outils lourds prennent le relais en CI. Présentez-la comme telle, jamais comme un certificat de sécurité.
L'autre face : le marché des skills malveillantes
Section intitulée « L'autre face : le marché des skills malveillantes »La sécurité va dans les deux sens. Les skills servent à auditer, mais elles sont aussi devenues une cible. Une étude Snyk (« ToxicSkills », 2026) a scanné près de 4 000 skills publiques : 13,4 % portaient une faille critique, et environ 37 % un problème de sécurité. Datadog a démontré qu'une skill piégée peut exfiltrer un secret via le dynamic context, exécuté avant que le modèle ne raisonne.
La conséquence pratique rejoint le guide sur le standard : n'installez jamais une skill de sécurité tierce sans l'auditer, exactement comme une dépendance. Une skill « d'audit » téléchargée à l'aveugle peut être le cheval de Troie. Lisez le SKILL.md, traquez les !`...` et les allowed-tools larges, et privilégiez vos propres skills d'audit, dont vous maîtrisez le code.
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Correction |
|---|---|---|
| La skill modifie des fichiers | allowed-tools trop large | Restreindre à Read, Grep, Glob |
| Trop de faux positifs | Motifs trop génériques | Cibler des patterns précis, exclure les tests |
| Findings non priorisés | Pas de cadre dans le SKILL.md | Demander l'annotation CWE de chaque finding |
| Secret raté | Format inhabituel | Compléter les motifs, et garder un vrai scan de secrets en CI |
| Audit pris pour une garantie | Rôle mal posé | Rappeler dans la sortie que c'est un premier passage |
À retenir
Section intitulée « À retenir »- Une skill d'audit est un filet shift-left, en lecture seule, déclenché à la demande.
- Restreignez son
allowed-toolsà la lecture : une skill de sécurité ne doit pas pouvoir écrire ni lancer un shell large. - Classez les findings avec le CWE (code) ; MITRE ATT&CK sert côté détection et réponse.
- Une skill ne remplace pas un SAST (Bandit, Semgrep, CodeQL) ni la CI : elle les précède.
- Les skills de sécurité tierces sont un risque : auditez-les comme des dépendances avant de les installer.