# ObsiGate — règles Semgrep locales (#87 T7). # # Volontairement LOCALES (aucun `--config auto`/registre) : le runner CI a un # accès réseau fragile, et ces règles n'ont besoin d'aucun téléchargement. # Exécution : `semgrep --config semgrep-rules/ backend/` (job CI `lint`, # bloquant). Chaque règle est un garde-fou : aucun code existant ne doit # la déclencher (vérifié à l'ajout) ; toute violation future échoue le CI. rules: - id: obsigate-no-eval-exec message: "Interdit : eval()/exec() sur du contenu dynamique (injection de code). Restructurer sans exécution de code." severity: ERROR languages: [python] pattern-either: - pattern: eval(...) - pattern: exec(...) - id: obsigate-no-shell-true message: "Interdit : subprocess avec shell=True (injection shell). Passer argv en liste, shell=False." severity: ERROR languages: [python] pattern-either: - pattern: subprocess.run(..., shell=True, ...) - pattern: subprocess.Popen(..., shell=True, ...) - pattern: subprocess.call(..., shell=True, ...) - pattern: subprocess.check_output(..., shell=True, ...) - pattern: subprocess.check_call(..., shell=True, ...) - id: obsigate-no-os-system message: "Interdit : os.system() (shell implicite). Utiliser subprocess avec argv en liste." severity: ERROR languages: [python] pattern: os.system(...) - id: obsigate-no-pickle-load message: "Interdit : pickle.load/loads sur des données non fiables (exécution arbitraire). Utiliser JSON." severity: ERROR languages: [python] pattern-either: - pattern: pickle.load(...) - pattern: pickle.loads(...) - id: obsigate-no-yaml-unsafe-load message: "Interdit : yaml.load() sans Loader (exécution arbitraire). Utiliser yaml.safe_load()." severity: ERROR languages: [python] patterns: - pattern: yaml.load(...) - pattern-not: yaml.load(..., Loader=...) - id: obsigate-no-unverified-tls message: "Interdit : verify=False (MITM). Ne jamais désactiver la vérification TLS." severity: ERROR languages: [python] pattern-either: - pattern: requests.$METHOD(..., verify=False, ...) - pattern: httpx.$METHOD(..., verify=False, ...) - pattern: httpx.Client(..., verify=False, ...) - pattern: httpx.AsyncClient(..., verify=False, ...) - id: obsigate-no-markupsafe-markup message: "Interdit : markupsafe.Markup() (contourne l'échappement XSS, BUG-021/022). Le sanitizer serveur est la seule voie." severity: ERROR languages: [python] pattern: Markup(...) - id: obsigate-no-tempfile-mktemp message: "Interdit : tempfile.mktemp() (race symlink, CWE-377). Utiliser NamedTemporaryFile/mkdtemp." severity: ERROR languages: [python] pattern: tempfile.mktemp(...)