PREUVE TECHNIQUE QA — Ticket #46 Domaine & application : SecurityFinding, normalisation Trivy/Semgrep, cle de dedup et format de ticket Date : 2026-06-11T18:49:57Z Branche / commit : feat/46-security-finding-domain @ 138e26e (PR #23 -> dev) Type : ticket back-end uniquement (hexagonal api/, couches domain + application). Pas d'HTTP, pas d'UI -> smoke = build/import + suites unitaires, pas de capture navigateur. Note : aucun secret dans cette preuve (payloads synthetiques, port en memoire ; aucun .env/cle/token imprime). ============================================================ 1) Suites unitaires ciblees (domaine + application securite) ============================================================ $ PYTHONPATH=src python -m pytest -q tests/test_security_value_objects.py tests/test_security_normalizers.py tests/test_create_tickets_from_scan.py .......................... [100%] 26 passed in 0.08s ============================================================ 2) Qualite statique ============================================================ $ ruff check . All checks passed! $ PYTHONPATH=src mypy src Success: no issues found in 114 source files ============================================================ 3) Suite back-end complete (Postgres ephemere pgvector:pg16 + alembic upgrade head) ============================================================ $ PYTHONPATH=src python -m pytest -q (DATABASE_URL pointant sur le conteneur pgvector ephemere) 398 passed, 1 skipped, 6 warnings in 34.77s ============================================================ 4) Smoke fonctionnel (import + execution sur payloads Trivy & Semgrep) ============================================================ === Trivy === source=trivy sev=HIGH dedup_key='lodash@4.17.20_CVE-2021-23337' source=trivy sev=MEDIUM dedup_key='CVE-2020-8203' titre: [Sécurité] Dépendance vulnérable : lodash@4.17.20 (CVE-2021-23337) === Semgrep === source=semgrep sev=HIGH dedup_key='api/src/app/exec.py:42_python.lang.security.dangerous-exec' titre: [Sécurité] Vulnérabilité de code : api/src/app/exec.py:42 (python.lang.security.dangerous-exec) description Semgrep: **Sévérité** : HIGH **Source** : Semgrep **Emplacement** : api/src/app/exec.py:42 **Règle** : python.lang.security.dangerous-exec Use of exec() is dangerous ### Extrait de code ``` exec(user_input) ``` ### Lien CVE https://owasp.org/exec OK dedup keys conformes au format documente === CreateTicketsFromScan (via port abstrait) === action=created issue=1000 key='lodash@4.17.20_CVE-2021-23337' action=regression issue=501 key='CVE-2020-8203' action=deduped issue=502 key='api/src/app/exec.py:42_python.lang.security.dangerous-exec' appels port: [('create', 'lodash@4.17.20_CVE-2021-23337'), ('reopen', 'CVE-2020-8203'), ('note', 'api/src/app/exec.py:42_python.lang.security.dangerous-exec')] OK decision dedup-vs-regression-vs-create pilotee par le port abstrait SMOKE #46 : PASS ============================================================ 5) Verdict par critere d'acceptation ============================================================ AC1 SecurityFinding + normaliseurs couvrent les 2 formats ............ OK (from_trivy/from_semgrep importent et tournent) AC2 Cle de dedup (Trivy CVE-{id} / {pkg}@{ver}_CVE-{id} ; Semgrep {file}:{line}_{rule-id}) ... OK (assertions vertes) AC3 Format de ticket (titre + description complete) .................. OK ([Securite] ..., sev/source/emplacement/extrait/lien/reco) AC4 CreateTicketsFromScan decide dedup vs regression via port abstrait OK (Protocol runtime-checkable ; create/regression/dedup) AC5 Tests unitaires verts ; ruff + mypy passent ..................... OK (26 ciblees + 398 suite ; ruff OK ; mypy OK) RESULTAT GLOBAL : PASS