forked from Spookymic/Infographies
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdevsecops_interactive.html
More file actions
486 lines (465 loc) · 30.3 KB
/
Copy pathdevsecops_interactive.html
File metadata and controls
486 lines (465 loc) · 30.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DevSecOps — SAST, DAST, SBOM, SLSA, Sigstore</title>
<style>
:root{--bg:#f8fafc;--card:#fff;--border:#e2e8f0;--text:#1e293b;--muted:#64748b;--acc:#a855f7;--acc2:#9333ea;--blue600:#2563eb;--green:#16a34a;--red:#dc2626;--orange:#ea580c;--purple:#7c3aed;--grad1:#1a0033;--grad2:#330066}
@media(prefers-color-scheme:dark){:root{--bg:#0d0d0d;--card:#1a1a1a;--border:#2a2a2a;--text:#e2e8f0;--muted:#94a3b8}}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:'Segoe UI',system-ui,sans-serif;background:var(--bg);color:var(--text);line-height:1.6}
header{background:linear-gradient(135deg,var(--grad1),var(--grad2));padding:2rem 1rem;text-align:center;border-bottom:2px solid var(--acc)}
header h1{font-size:2rem;font-weight:800;color:#fff}
header p{color:#d8b4fe;margin-top:.4rem;font-size:.95rem}
nav{position:sticky;top:0;z-index:100;background:var(--card);border-bottom:1px solid var(--border);padding:.5rem 1rem;display:flex;gap:.5rem;flex-wrap:wrap;justify-content:center}
.tab-btn{padding:.4rem 1rem;border:none;border-radius:999px;cursor:pointer;font-size:.85rem;font-weight:600;background:var(--border);color:var(--muted);transition:all .2s}
.tab-btn.active{background:var(--blue600);color:#fff}
.tab-btn:hover:not(.active){background:var(--acc);color:#fff}
section{display:none;max-width:1100px;margin:0 auto;padding:1.5rem 1rem}
section.active{display:block}
h2{font-size:1.4rem;font-weight:700;margin-bottom:1rem;color:var(--acc)}
h3{font-size:1.1rem;font-weight:600;margin:1.2rem 0 .6rem}
.grid{display:grid;gap:1rem}.g2{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}.g3{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}
.card{background:var(--card);border:1px solid var(--border);border-radius:.75rem;padding:1.2rem}
.card h4{font-size:1rem;font-weight:700;margin-bottom:.5rem;color:var(--acc)}
.codeblk{background:#1e1e2e;color:#cdd6f4;border-radius:.5rem;padding:1rem;font-family:'Cascadia Code','Fira Code',monospace;font-size:.82rem;overflow-x:auto;margin:.5rem 0;line-height:1.7;white-space:pre-wrap}
.c-kw{color:#89b4fa}.c-str{color:#a6e3a1}.c-comment{color:#6c7086;font-style:italic}.c-val{color:#f9e2af}.c-fn{color:#cba6f7}
table{width:100%;border-collapse:collapse;font-size:.85rem;margin:.5rem 0}
th{background:var(--acc);color:#fff;padding:.5rem .75rem;text-align:left}
td{padding:.45rem .75rem;border-bottom:1px solid var(--border)}
tr:hover td{background:var(--border)}
.info-box{background:var(--card);border-left:4px solid var(--acc);border-radius:.5rem;padding:.8rem 1rem;margin:.5rem 0}
.info-box.green{border-color:var(--green)}.info-box.red{border-color:var(--red)}.info-box.blue{border-color:var(--blue600)}.info-box.orange{border-color:var(--orange)}
.shift-left{display:flex;gap:.3rem;flex-wrap:wrap;margin:.5rem 0}
.stage{padding:.6rem;background:var(--card);border:1px solid var(--border);border-top:3px solid var(--acc);border-radius:.4rem;font-size:.82rem;flex:1;min-width:120px;text-align:center}
.stage strong{display:block;color:var(--acc);margin-bottom:.3rem}
.quiz-q{background:var(--card);border:1px solid var(--border);border-radius:.75rem;padding:1.2rem;margin:.8rem 0}
.quiz-q p{font-weight:600;margin-bottom:.7rem}
.quiz-opt{padding:.5rem .8rem;border:1px solid var(--border);border-radius:.4rem;margin:.3rem 0;cursor:pointer;transition:all .2s}
.quiz-opt:hover{border-color:var(--acc);background:rgba(168,85,247,.05)}
.quiz-opt.correct{background:#dcfce7;border-color:var(--green);color:#166534}
.quiz-opt.wrong{background:#fee2e2;border-color:var(--red);color:#991b1b}
@media(prefers-color-scheme:dark){.quiz-opt.correct{background:#14532d;color:#86efac}.quiz-opt.wrong{background:#450a0a;color:#fca5a5}}
#quiz-score{display:none;text-align:center;padding:1.5rem;background:var(--card);border-radius:.75rem;margin-top:1rem;font-size:1.1rem;font-weight:700}
</style>
</head>
<body>
<header>
<h1>DevSecOps</h1>
<p>Shift-left, SAST/DAST/IAST/RASP, SBOM, SLSA, Sigstore, supply chain</p>
</header>
<nav>
<button class="tab-btn active" onclick="showTab('overview')">Vue d'ensemble</button>
<button class="tab-btn" onclick="showTab('sast')">SAST & DAST</button>
<button class="tab-btn" onclick="showTab('supply')">Supply Chain</button>
<button class="tab-btn" onclick="showTab('sbom')">SBOM & Sigstore</button>
<button class="tab-btn" onclick="showTab('pipeline')">Pipeline sécurisé</button>
<button class="tab-btn" onclick="showTab('quiz')">Quiz</button>
</nav>
<section id="overview" class="active">
<h2>Vue d'ensemble</h2>
<div class="grid g2">
<div class="card">
<h4>DevSecOps</h4>
<div class="info-box">
<strong>DevSecOps = intégrer la sécurité dans le pipeline DevOps, le plus tôt possible (shift-left).</strong> Au lieu d'auditer après coup, on automatise des contrôles à chaque étape.
</div>
<div class="info-box green" style="margin-top:.4rem">
Bénéfices :
<ul style="padding-left:1.2rem;margin-top:.3rem">
<li>Détection précoce (coût ×10 par étape ratée)</li>
<li>Responsabilité partagée Dev + Sec + Ops</li>
<li>Conformité comme code</li>
<li>Vélocité préservée (pas de gate manuelle bloquante)</li>
</ul>
</div>
</div>
<div class="card">
<h4>Shift-left — sécurité dans le pipeline</h4>
<div class="shift-left">
<div class="stage"><strong>Design</strong>Threat modeling, secure design</div>
<div class="stage"><strong>Code</strong>IDE plugins, secret scanning, pre-commit</div>
<div class="stage"><strong>Build</strong>SAST, SCA, container scan</div>
<div class="stage"><strong>Test</strong>DAST, IAST, fuzzing</div>
<div class="stage"><strong>Deploy</strong>IaC scan, admission control</div>
<div class="stage"><strong>Run</strong>RASP, EDR, runtime monitoring</div>
</div>
<div class="info-box orange" style="margin-top:.5rem;font-size:.82rem">
<strong>Règle 1-10-100 :</strong> 1€ pour fixer un bug en design, 10€ en dev, 100€ en prod, 1000€+ après breach.
</div>
</div>
</div>
<div class="card" style="margin-top:1rem">
<h4>Glossaire</h4>
<table>
<tr><th>Acronyme</th><th>Description</th></tr>
<tr><td>SAST</td><td>Static Application Security Testing — analyse du code source</td></tr>
<tr><td>DAST</td><td>Dynamic — analyse de l'app en cours d'exécution</td></tr>
<tr><td>IAST</td><td>Interactive — instrumentation runtime + SAST</td></tr>
<tr><td>RASP</td><td>Runtime Application Self-Protection — bloque les attaques live</td></tr>
<tr><td>SCA</td><td>Software Composition Analysis — dépendances tierces</td></tr>
<tr><td>SBOM</td><td>Software Bill of Materials — inventaire des composants</td></tr>
<tr><td>SLSA</td><td>Supply chain Levels for Software Artifacts</td></tr>
<tr><td>SAST/DAST/IAST/RASP</td><td>= les 4 acronymes côté code</td></tr>
<tr><td>CSPM</td><td>Cloud Security Posture Management</td></tr>
<tr><td>CWPP</td><td>Cloud Workload Protection Platform</td></tr>
<tr><td>CNAPP</td><td>Cloud Native Application Protection — combine CSPM+CWPP</td></tr>
<tr><td>CIS Benchmarks</td><td>Standards de hardening (Docker, K8s, Linux, AWS…)</td></tr>
</table>
</div>
</section>
<section id="sast">
<h2>SAST & DAST</h2>
<div class="grid g2">
<div class="card">
<h4>SAST — Static Application Security Testing</h4>
<p style="font-size:.88rem;margin-bottom:.5rem">Analyse le code source <strong>sans exécution</strong>. Détecte les patterns vulnérables (injection SQL, XSS, deserialization unsafe, secrets en clair…).</p>
<table>
<tr><th>Outil</th><th>Notes</th></tr>
<tr><td>Semgrep</td><td>Open source, rules custom faciles, multi-langage</td></tr>
<tr><td>SonarQube / SonarCloud</td><td>Plus complet (qualité + sec), bug tracking intégré</td></tr>
<tr><td>CodeQL (GitHub)</td><td>Très puissant (graph query), gratuit en open source</td></tr>
<tr><td>Bandit</td><td>Python uniquement, léger</td></tr>
<tr><td>Gosec</td><td>Go uniquement</td></tr>
<tr><td>Brakeman</td><td>Ruby on Rails</td></tr>
<tr><td>Checkmarx, Veracode</td><td>Commercial enterprise</td></tr>
</table>
<div class="info-box orange" style="margin-top:.4rem;font-size:.82rem">
<strong>Faux positifs fréquents.</strong> Tuner les règles, baseline initiale, "fix-forward" plutôt que tout fixer d'un coup.
</div>
</div>
<div class="card">
<h4>DAST — Dynamic</h4>
<p style="font-size:.88rem;margin-bottom:.5rem">Teste l'app <strong>en cours d'exécution</strong>. Envoie des payloads malveillants et observe les réponses. Trouve les bugs runtime (auth, sessions, business logic).</p>
<table>
<tr><th>Outil</th><th>Notes</th></tr>
<tr><td>OWASP ZAP</td><td>Open source, scriptable, scan automatique + manuel</td></tr>
<tr><td>Burp Suite</td><td>Référence des pentesters, version Pro payante</td></tr>
<tr><td>Nuclei</td><td>Templates YAML — très rapide, détection de CVE</td></tr>
<tr><td>Nikto</td><td>Web server scanner classique</td></tr>
<tr><td>sqlmap</td><td>Spécialisé injection SQL</td></tr>
<tr><td>StackHawk, Acunetix</td><td>Commercial, intégration CI</td></tr>
</table>
<div class="info-box red" style="margin-top:.4rem;font-size:.82rem">
DAST = lent (minutes à heures). À lancer en async hors du critical path PR, ou sur staging la nuit.
</div>
</div>
</div>
<div class="grid g2" style="margin-top:1rem">
<div class="card">
<h4>IAST & RASP</h4>
<div class="info-box blue">
<strong>IAST</strong> : agent dans l'app pendant les tests fonctionnels. Voit le code + l'exécution → précision élevée, peu de faux positifs.
</div>
<div class="info-box purple" style="margin-top:.4rem">
<strong>RASP</strong> : protection runtime en production. Détecte ET bloque (ex: injection SQL au moment de l'exécution). Type Contrast Security, Sqreen (Datadog).
</div>
<div class="info-box orange" style="margin-top:.4rem;font-size:.82rem">
IAST/RASP = overhead CPU non négligeable. Réservé aux apps critiques.
</div>
</div>
<div class="card">
<h4>Secret scanning</h4>
<div class="info-box red">
Découvrir les secrets (API keys, tokens, certificats) commités par erreur. Critique car un secret leaké = exploitable immédiatement.
</div>
<table style="margin-top:.4rem">
<tr><th>Outil</th><th>Usage</th></tr>
<tr><td>git-secrets</td><td>Pre-commit hook AWS</td></tr>
<tr><td>trufflehog</td><td>Scan historique git + détection entropie</td></tr>
<tr><td>gitleaks</td><td>Pre-commit + CI, regex paramétrable</td></tr>
<tr><td>GitHub secret scanning</td><td>Natif, alertes au push, validity check</td></tr>
<tr><td>GitGuardian</td><td>SaaS, monitoring continu</td></tr>
</table>
<div class="info-box green" style="margin-top:.4rem;font-size:.82rem">
<strong>Si secret leaké :</strong> rotate immédiatement. Le retirer du code ne suffit pas — l'historique git reste, et les bots l'ont déjà cloné.
</div>
</div>
</div>
</section>
<section id="supply">
<h2>Supply Chain Security</h2>
<div class="grid g2">
<div class="card">
<h4>Attaques connues</h4>
<table>
<tr><th>Année</th><th>Incident</th></tr>
<tr><td>2017</td><td>NotPetya via M.E.Doc (Ukraine)</td></tr>
<tr><td>2018</td><td>event-stream npm — code malveillant ajouté par un mainteneur</td></tr>
<tr><td>2020</td><td>SolarWinds — backdoor dans build pipeline → 18000 victimes (DHS, MSFT…)</td></tr>
<tr><td>2021</td><td>Codecov — bash uploader compromis → secrets CI volés</td></tr>
<tr><td>2021</td><td>Log4Shell — vuln dans Log4j, ~ tous les serveurs Java</td></tr>
<tr><td>2024</td><td>XZ Utils — backdoor par contributeur infiltré 2 ans</td></tr>
<tr><td>2024</td><td>polyfill.io — domaine racheté, JS malveillant injecté sur 100k sites</td></tr>
</table>
<div class="info-box red" style="margin-top:.4rem;font-size:.82rem">
<strong>Le code que vous écrivez est ~5% de votre application.</strong> Les 95% restants sont des dépendances : protégez-les autant que votre propre code.
</div>
</div>
<div class="card">
<h4>SCA — Software Composition Analysis</h4>
<p style="font-size:.88rem;margin-bottom:.5rem">Inventorier toutes les dépendances et croiser avec les CVE connues.</p>
<table>
<tr><th>Outil</th><th>Usage</th></tr>
<tr><td>Dependabot (GitHub)</td><td>Alerts + PR automatique de mise à jour, natif</td></tr>
<tr><td>Renovate</td><td>OSS, plus configurable que Dependabot</td></tr>
<tr><td>Snyk</td><td>SaaS, multi-langage, license check</td></tr>
<tr><td>OWASP Dependency-Check</td><td>OSS, CVE matching</td></tr>
<tr><td>npm audit / pip-audit / cargo audit</td><td>Natifs aux ecosystems</td></tr>
<tr><td>Trivy</td><td>FS + images + IaC</td></tr>
<tr><td>Grype</td><td>Container scanning, partenaire Syft</td></tr>
</table>
</div>
</div>
<div class="grid g2" style="margin-top:1rem">
<div class="card">
<h4>Container scanning</h4>
<div class="codeblk"><span class="c-comment"># Trivy — scan local d'une image</span>
trivy image nginx:<span class="c-val">1.27</span>
<span class="c-comment"># Affiche CVE + criticité + version corrigée</span>
<span class="c-comment"># Scan d'un Dockerfile et de l'image construite</span>
trivy config Dockerfile
trivy image --severity CRITICAL,HIGH myapp:latest
<span class="c-comment"># Scan d'un repo git complet</span>
trivy fs --scanners vuln,secret,misconfig .
<span class="c-comment"># Intégration GitHub Actions</span>
- <span class="c-kw">uses</span>: aquasecurity/trivy-action@<span class="c-val">master</span>
<span class="c-kw">with</span>:
<span class="c-kw">image-ref</span>: <span class="c-str">'myapp:${{ github.sha }}'</span>
<span class="c-kw">severity</span>: <span class="c-str">'CRITICAL,HIGH'</span>
<span class="c-kw">exit-code</span>: <span class="c-str">'1'</span> <span class="c-comment"># break la CI sur findings</span></div>
</div>
<div class="card">
<h4>SLSA — Supply chain Levels for Software Artifacts</h4>
<p style="font-size:.88rem;margin-bottom:.5rem">Framework Google (CNCF) pour mesurer la maturité de la chaîne de build.</p>
<table>
<tr><th>Level</th><th>Exigence</th></tr>
<tr><td>SLSA 1</td><td>Build documenté (provenance basique)</td></tr>
<tr><td>SLSA 2</td><td>Build hébergé + provenance authentifiée (signature)</td></tr>
<tr><td>SLSA 3</td><td>Build isolé (hermétique), non-falsifiable</td></tr>
<tr><td>SLSA 4</td><td>Two-person reviewed, hermétique, reproductible</td></tr>
</table>
<div class="info-box blue" style="margin-top:.4rem;font-size:.82rem">
GitHub Actions atteint SLSA 3 nativement via les <em>artifact attestations</em>.
</div>
</div>
</div>
<div class="card" style="margin-top:1rem">
<h4>Bonnes pratiques supply chain</h4>
<div class="grid g3">
<div class="info-box green"><strong>Pin versions</strong><br>Lockfile (package-lock.json, Cargo.lock, poetry.lock). Hash checking quand possible.</div>
<div class="info-box blue"><strong>Registry privé</strong><br>Artifactory, Nexus, GitHub Packages — mirror et scan avant utilisation.</div>
<div class="info-box purple"><strong>Vendoring</strong><br>Pour deps critiques : vendoriser dans le repo (Go vendor, npm ci avec lockfile)</div>
<div class="info-box orange"><strong>Audit régulier</strong><br>Hebdomadaire en CI, alertes pour CVE critiques (CVSS > 7)</div>
<div class="info-box red"><strong>Minimal deps</strong><br>Moins de deps = moins de surface. Évaluer maintainability avant import.</div>
<div class="info-box"><strong>Builds hermétiques</strong><br>Pas de network access pendant le build. Reproductibilité.</div>
</div>
</div>
</section>
<section id="sbom">
<h2>SBOM & Sigstore</h2>
<div class="grid g2">
<div class="card">
<h4>SBOM — Software Bill of Materials</h4>
<div class="info-box">
Inventaire exhaustif des composants d'un logiciel (dépendances directes et transitives, versions, licences, hashs). Exigé par US Executive Order 14028, NIS2, et de plus en plus de contrats.
</div>
<table style="margin-top:.4rem">
<tr><th>Format</th><th>Origine</th></tr>
<tr><td>SPDX</td><td>Linux Foundation, ISO/IEC 5962:2021</td></tr>
<tr><td>CycloneDX</td><td>OWASP, JSON/XML/Protobuf</td></tr>
<tr><td>SWID</td><td>ISO/IEC 19770-2, plus rare</td></tr>
</table>
<div class="codeblk" style="margin-top:.4rem"><span class="c-comment"># Syft — génération SBOM</span>
syft myimage:<span class="c-val">latest</span> -o cyclonedx-json=sbom.json
syft myimage:<span class="c-val">latest</span> -o spdx-json=sbom.spdx.json
<span class="c-comment"># Grype : scanner un SBOM contre les CVE</span>
grype sbom:./sbom.json --fail-on high
<span class="c-comment"># GitHub : génération auto à chaque release</span>
- <span class="c-kw">uses</span>: anchore/sbom-action@<span class="c-val">v0</span></div>
</div>
<div class="card">
<h4>Sigstore — signature simplifiée</h4>
<p style="font-size:.88rem;margin-bottom:.5rem">Projet Linux Foundation. Signer les artefacts sans gérer de PKI complexe : utilise des certificats <strong>éphémères</strong> liés à l'identité OIDC.</p>
<div class="info-box green">
<strong>3 composants :</strong>
<ul style="padding-left:1.2rem;margin-top:.3rem">
<li><strong>cosign</strong> : signature de containers et fichiers</li>
<li><strong>Fulcio</strong> : émet des certs courte durée (10 min) liés à OIDC</li>
<li><strong>Rekor</strong> : log de transparence public (append-only)</li>
</ul>
</div>
<div class="codeblk" style="margin-top:.4rem"><span class="c-comment"># Signature keyless (sans clé locale)</span>
cosign sign $REGISTRY/myapp:<span class="c-val">v1.0</span>
<span class="c-comment"># Ouvre browser → login OIDC → cert généré
# → signature uploadée + entrée dans Rekor</span>
<span class="c-comment"># Vérification</span>
cosign verify $REGISTRY/myapp:<span class="c-val">v1.0</span> \
--certificate-identity=<span class="c-str">"github-action@..."</span> \
--certificate-oidc-issuer=<span class="c-str">"https://token.actions.githubusercontent.com"</span>
<span class="c-comment"># Attestation SLSA</span>
cosign attest --predicate sbom.json myapp:<span class="c-val">v1.0</span></div>
</div>
</div>
<div class="grid g2" style="margin-top:1rem">
<div class="card">
<h4>Admission control K8s</h4>
<p style="font-size:.88rem;margin-bottom:.5rem">Bloquer le déploiement d'images non signées ou non conformes :</p>
<table>
<tr><th>Outil</th><th>Notes</th></tr>
<tr><td>Kyverno</td><td>Policies déclaratives YAML, mature</td></tr>
<tr><td>OPA Gatekeeper</td><td>Rego language, flexible</td></tr>
<tr><td>Connaisseur, Cosigned</td><td>Spécialisés signature cosign</td></tr>
<tr><td>Sigstore policy-controller</td><td>Officiel Sigstore</td></tr>
</table>
<div class="codeblk" style="margin-top:.4rem"><span class="c-comment"># Kyverno — exiger signature cosign</span>
<span class="c-kw">apiVersion</span>: kyverno.io/v1
<span class="c-kw">kind</span>: ClusterPolicy
<span class="c-kw">metadata</span>: { <span class="c-kw">name</span>: verify-signatures }
<span class="c-kw">spec</span>:
<span class="c-kw">validationFailureAction</span>: Enforce
<span class="c-kw">rules</span>:
- <span class="c-kw">name</span>: verify-cosign
<span class="c-kw">match</span>: { <span class="c-kw">any</span>: [{<span class="c-kw">resources</span>:{<span class="c-kw">kinds</span>:[Pod]}}] }
<span class="c-kw">verifyImages</span>:
- <span class="c-kw">imageReferences</span>: [<span class="c-str">"myregistry.io/*"</span>]
<span class="c-kw">attestors</span>:
- <span class="c-kw">entries</span>:
- <span class="c-kw">keyless</span>:
<span class="c-kw">subject</span>: <span class="c-str">"github-actions@..."</span></div>
</div>
<div class="card">
<h4>VEX — Vulnerability Exploitability eXchange</h4>
<div class="info-box blue">
<strong>Problème :</strong> un SBOM révèle des CVE dans des dépendances. Mais beaucoup ne sont <em>pas exploitables</em> dans votre contexte (chemin de code non utilisé).
</div>
<div class="info-box green" style="margin-top:.4rem">
<strong>VEX</strong> documente le statut d'exploitabilité par CVE : <em>not_affected</em>, <em>affected</em>, <em>fixed</em>, <em>under_investigation</em>. Réduit la fatigue des alertes.
</div>
<div class="codeblk" style="margin-top:.4rem"><span class="c-comment"># OpenVEX (Linux Foundation)</span>
{
<span class="c-str">"@context"</span>: <span class="c-str">"https://openvex.dev/ns/v0.2.0"</span>,
<span class="c-str">"statements"</span>: [{
<span class="c-str">"vulnerability"</span>: {<span class="c-str">"@id"</span>:<span class="c-str">"CVE-2024-1234"</span>},
<span class="c-str">"products"</span>: [{<span class="c-str">"@id"</span>:<span class="c-str">"pkg:oci/myapp@v1.0"</span>}],
<span class="c-str">"status"</span>: <span class="c-str">"not_affected"</span>,
<span class="c-str">"justification"</span>: <span class="c-str">"vulnerable_code_not_in_execute_path"</span>
}]
}</div>
</div>
</div>
</section>
<section id="pipeline">
<h2>Pipeline DevSecOps complet</h2>
<div class="card">
<h4>GitHub Actions — exemple sécurisé</h4>
<div class="codeblk"><span class="c-kw">name</span>: Secure CI
<span class="c-kw">on</span>: [pull_request]
<span class="c-kw">permissions</span>: <span class="c-comment"># least privilege</span>
<span class="c-kw">contents</span>: read
<span class="c-kw">security-events</span>: write <span class="c-comment"># pour upload SARIF</span>
<span class="c-kw">id-token</span>: write <span class="c-comment"># OIDC vers cloud</span>
<span class="c-kw">jobs</span>:
<span class="c-fn">secrets-scan</span>:
<span class="c-kw">runs-on</span>: ubuntu-latest
<span class="c-kw">steps</span>:
- <span class="c-kw">uses</span>: actions/checkout@v4
<span class="c-kw">with</span>: { <span class="c-kw">fetch-depth</span>: <span class="c-val">0</span> }
- <span class="c-kw">uses</span>: gitleaks/gitleaks-action@v2
<span class="c-fn">sast</span>:
<span class="c-kw">runs-on</span>: ubuntu-latest
<span class="c-kw">steps</span>:
- <span class="c-kw">uses</span>: actions/checkout@v4
- <span class="c-kw">uses</span>: returntocorp/semgrep-action@v1
<span class="c-kw">with</span>: { <span class="c-kw">config</span>: <span class="c-str">"p/owasp-top-ten p/security-audit"</span> }
- <span class="c-kw">uses</span>: github/codeql-action/init@v3
<span class="c-kw">with</span>: { <span class="c-kw">languages</span>: javascript }
- <span class="c-kw">uses</span>: github/codeql-action/analyze@v3
<span class="c-fn">sca</span>:
<span class="c-kw">runs-on</span>: ubuntu-latest
<span class="c-kw">steps</span>:
- <span class="c-kw">uses</span>: actions/checkout@v4
- <span class="c-kw">uses</span>: aquasecurity/trivy-action@master
<span class="c-kw">with</span>:
<span class="c-kw">scan-type</span>: fs
<span class="c-kw">scanners</span>: vuln,secret,misconfig
<span class="c-kw">severity</span>: CRITICAL,HIGH
<span class="c-kw">exit-code</span>: <span class="c-str">'1'</span>
<span class="c-fn">iac-scan</span>:
<span class="c-kw">runs-on</span>: ubuntu-latest
<span class="c-kw">steps</span>:
- <span class="c-kw">uses</span>: actions/checkout@v4
- <span class="c-kw">uses</span>: bridgecrewio/checkov-action@master
<span class="c-kw">with</span>: { <span class="c-kw">directory</span>: <span class="c-str">"infra/"</span> }
<span class="c-fn">container-build</span>:
<span class="c-kw">needs</span>: [secrets-scan, sast, sca]
<span class="c-kw">runs-on</span>: ubuntu-latest
<span class="c-kw">steps</span>:
- <span class="c-kw">uses</span>: actions/checkout@v4
- <span class="c-kw">uses</span>: docker/build-push-action@v5
<span class="c-kw">with</span>:
<span class="c-kw">push</span>: <span class="c-val">true</span>
<span class="c-kw">tags</span>: ghcr.io/${{ github.repository }}:${{ github.sha }}
<span class="c-kw">provenance</span>: <span class="c-val">true</span> <span class="c-comment"># SLSA 3</span>
<span class="c-kw">sbom</span>: <span class="c-val">true</span> <span class="c-comment"># SBOM SPDX inclus</span>
- <span class="c-kw">uses</span>: sigstore/cosign-installer@v3
- <span class="c-kw">run</span>: cosign sign --yes ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}</div>
</div>
<div class="grid g2" style="margin-top:1rem">
<div class="card">
<h4>Métriques DevSecOps</h4>
<table>
<tr><th>Métrique</th><th>Cible</th></tr>
<tr><td>% PR scannées SAST</td><td>100%</td></tr>
<tr><td>Mean time to remediate (CVE critique)</td><td>< 7 jours</td></tr>
<tr><td>% deps avec CVE high+</td><td>< 1%</td></tr>
<tr><td>% images signées avant deploy</td><td>100%</td></tr>
<tr><td>Couverture SBOM</td><td>100% des releases</td></tr>
<tr><td>False positive rate SAST</td><td>< 20% (tuning continu)</td></tr>
<tr><td>Pre-commit hook adoption</td><td>> 80% des dev</td></tr>
</table>
</div>
<div class="card">
<h4>Maturité — Builds reproductibles & hermétiques</h4>
<div class="info-box green">
<strong>Reproducible builds :</strong> même source = même binaire byte-pour-byte. Détecte les modifications malicieuses du toolchain. Pratique : Bazel, Nix, Buck2.
</div>
<div class="info-box blue" style="margin-top:.4rem">
<strong>Hermetic builds :</strong> aucun accès réseau pendant le build. Toutes les deps pré-fetched et hashées. Élimine le risque "le mainteneur a push une mauvaise version".
</div>
<div class="info-box purple" style="margin-top:.4rem">
<strong>Build provenance (in-toto) :</strong> attestation cryptographique de qui a build quoi, où, quand, avec quel code. Standard SLSA.
</div>
</div>
</div>
</section>
<section id="quiz">
<h2>Quiz — DevSecOps</h2>
<div id="quiz-container"></div>
<div id="quiz-score"></div>
</section>
<script>
function showTab(id){document.querySelectorAll('section').forEach(s=>s.classList.remove('active'));document.querySelectorAll('.tab-btn').forEach(b=>b.classList.remove('active'));document.getElementById(id).classList.add('active');event.target.classList.add('active')}
const quizData=[
{q:"Quel est le principe du 'shift-left' en DevSecOps ?",opts:["Déplacer la prod vers la gauche","Détecter les problèmes de sécurité le plus tôt possible dans le SDLC","Faire les tests à droite","Aucun"],a:1},
{q:"Quelle est la différence entre SAST et DAST ?",opts:["Aucune","SAST analyse le code source statiquement, DAST teste l'app en cours d'exécution","SAST est cloud","DAST est en local"],a:1},
{q:"Que documente un SBOM ?",opts:["Le code source","L'inventaire complet des composants et dépendances d'un logiciel","Les bugs","Les performances"],a:1},
{q:"Quel format SBOM est promu par OWASP ?",opts:["SPDX","CycloneDX","SWID","XML"],a:1},
{q:"À quoi sert Sigstore ?",opts:["À chiffrer","Signer des artefacts sans gérer de PKI (certs éphémères + transparency log)","À scanner","À builder"],a:1},
{q:"Quel niveau SLSA exige un build hermétique non-falsifiable ?",opts:["SLSA 1","SLSA 2","SLSA 3","SLSA 4"],a:2},
{q:"Quel outil détecte les secrets commités par erreur dans Git ?",opts:["nmap","gitleaks / trufflehog","strace","gcc"],a:1},
{q:"Si un secret est leaké dans un commit, que faire en priorité ?",opts:["Rien","Le retirer du code","Rotater (renouveler) le secret immédiatement — le retirer du code ne suffit pas","Faire un PR"],a:2},
{q:"À quoi sert VEX (Vulnerability Exploitability eXchange) ?",opts:["Détecter les CVE","Documenter le statut d'exploitabilité d'une CVE dans un produit (réduit la fatigue d'alertes)","Patcher","Compresser"],a:1},
{q:"Quel outil K8s peut bloquer le déploiement d'une image non signée ?",opts:["kubectl","Kyverno / OPA Gatekeeper","Helm","kubelet"],a:1},
{q:"Quel est le plus gros incident supply chain de 2024 ?",opts:["SolarWinds","Log4Shell","XZ Utils backdoor","Heartbleed"],a:2},
{q:"Pourquoi un IAST a moins de faux positifs qu'un SAST pur ?",opts:["Il scanne moins","Il combine analyse de code + instrumentation runtime pendant les tests fonctionnels","Il est plus rapide","Il ignore les fichiers"],a:1},
{q:"Quelle est la règle 1-10-100 ?",opts:["Vitesse de scan","Coût croissant d'un bug : 1€ en design, 10€ en dev, 100€ en prod","Hiérarchie des sévérités","Niveau de log"],a:1}
];
let answers=new Array(quizData.length).fill(null);
function buildQuiz(){const c=document.getElementById('quiz-container');c.innerHTML=quizData.map((q,i)=>`<div class="quiz-q"><p>${i+1}. ${q.q}</p>${q.opts.map((o,j)=>`<div class="quiz-opt" onclick="answer(this,${i},${j})">${o}</div>`).join('')}</div>`).join('')}
function answer(el,qi,oi){const parent=el.parentElement;if(parent.querySelector('.correct,.wrong'))return;answers[qi]=oi;const correct=quizData[qi].a;parent.querySelectorAll('.quiz-opt').forEach((o,j)=>{if(j===correct)o.classList.add('correct');else if(j===oi&&oi!==correct)o.classList.add('wrong')});if(answers.every(a=>a!==null)){const score=answers.filter((a,i)=>a===quizData[i].a).length;const sc=document.getElementById('quiz-score');sc.style.display='block';sc.innerHTML=`Score : ${score}/${quizData.length} ${score>=10?'Excellent !':score>=7?'Bien !':'À revoir'}`}}
buildQuiz();
</script>
</body>
</html>