Files
afrov2/security_review.md
2026-04-23 10:22:01 +02:00

8.9 KiB

Revue de Sécurité - Afropreunariat

Ce document détaille une revue de sécurité complète de l'application Afropreunariat (basée sur Next.js, Prisma et PostgreSQL). Il identifie les menaces potentielles, les vulnérabilités courantes associées à cette pile technologique, et propose des solutions concrètes pour s'en prémunir.


1. Cross-Site Scripting (XSS)

La menace : Le XSS survient lorsqu'un attaquant parvient à injecter du code JavaScript malveillant dans les pages web consultées par d'autres utilisateurs. Cela permet de voler des sessions, de rediriger les utilisateurs ou de modifier le contenu du site.

Vulnérabilité identifiée sur le projet : L'application utilise massivement la propriété dangerouslySetInnerHTML pour afficher du contenu riche (articles de blog, événements, fiches entreprises, etc.) :

  • app/blog/[id]/page.tsx
  • app/afrolife/[id]/page.tsx
  • components/EventTimeline.tsx
  • app/cgv/page.tsx, app/cgu/page.tsx

Si le contenu inséré dans dangerouslySetInnerHTML provient des utilisateurs (via un éditeur WYSIWYG dans le panel admin par exemple) et n'est pas "nettoyé" (sanitized), un attaquant pourrait inclure une balise <script> malveillante.

Comment corriger :

  • Sanitisation : Ne faites jamais confiance au contenu HTML en base de données. Utilisez une librairie de nettoyage (sanitizer) comme isomorphic-dompurify ou dompurify avant d'afficher le contenu.
    import DOMPurify from 'isomorphic-dompurify';
    
    // Au lieu de :
    // <div dangerouslySetInnerHTML={{ __html: post.content }} />
    
    // Faites ceci :
    const cleanHTML = DOMPurify.sanitize(post.content);
    <div dangerouslySetInnerHTML={{ __html: cleanHTML }} />
    
  • CSP (Content Security Policy) : Configurez des en-têtes CSP restrictifs dans next.config.js pour empêcher l'exécution de scripts non autorisés (inline scripts).

2. Injections SQL (SQLi)

La menace : Un attaquant manipule les requêtes envoyées à la base de données en injectant du code SQL pour lire, modifier ou supprimer des données de manière non autorisée.

État actuel du projet : L'utilisation de Prisma ORM protège nativement l'application contre les injections SQL grâce à l'utilisation de requêtes paramétrées en coulisse (ex: prisma.event.findMany(...)).

Comment maintenir la sécurité :

  • Évitez d'utiliser les fonctions Prisma non sécurisées telles que $queryRawUnsafe ou $executeRawUnsafe.
  • Si vous devez utiliser des requêtes brutes, utilisez TOUJOURS $queryRaw ou $executeRaw (sans le suffixe Unsafe), qui paramètrent automatiquement les variables grâce aux tagged templates literals (ex: prisma.$queryRaw\SELECT * FROM User WHERE id = ${id}``).

3. Gestion de l'Authentification et des Sessions

La menace : Le vol d'identifiants, l'usurpation d'identité ou la falsification de session.

Vulnérabilité identifiée sur le projet : Le projet stocke apparemment l'utilisateur dans le stockage local du navigateur (localStorage.getItem('afro_user') dans UserProvider.tsx).

  • Le localStorage est directement lisible par n'importe quel code JavaScript s'exécutant sur la page.
  • Si une faille XSS est exploitée (voir point 1), l'attaquant peut lire le localStorage et voler la session de l'utilisateur (ou son token JWT s'il y est stocké).

Comment corriger :

  • Cookies HttpOnly : Stockez les jetons d'authentification (JWT) ou les identifiants de session dans des cookies sécurisés (HttpOnly, Secure, SameSite=Lax ou Strict). Un cookie HttpOnly ne peut pas être lu par JavaScript, ce qui atténue grandement l'impact d'une faille XSS.
  • Si NextAuth.js (Auth.js) n'est pas utilisé, envisagez de migrer vers ce standard qui gère nativement la sécurité des cookies.

4. Cross-Site Request Forgery (CSRF)

La menace : Le CSRF force un utilisateur authentifié à exécuter des actions non désirées sur une application web dans laquelle il est actuellement authentifié (ex: suppression de compte, modification de mot de passe) via un lien malveillant ou un formulaire caché sur un autre site.

Comment corriger :

  • Server Actions : Si vous utilisez les Server Actions de Next.js ("use server"), Next.js inclut une protection CSRF native (via la vérification des en-têtes Origin et Host).
  • API Routes (REST) : Si vous utilisez des routes d'API (app/api/...) modifiant des données (POST, PUT, DELETE), assurez-vous que les cookies de session utilisent l'attribut SameSite: 'Lax' ou SameSite: 'Strict'. Cela empêche le navigateur d'envoyer le cookie si la requête provient d'un autre domaine.

5. Contrôle d'Accès et Autorisations (Broken Access Control)

La menace : Un utilisateur accède à des ressources ou exécute des actions qu'il n'est pas censé pouvoir faire (ex: un utilisateur normal modifiant les réglages du site, ou accédant aux données d'une autre entreprise). On parle d'IDOR (Insecure Direct Object Reference).

Comment corriger :

  • Vérification systématique côté serveur : Ne vous fiez jamais au front-end pour bloquer l'accès. Dans chaque Route API (GET, POST, DELETE) ou Action Serveur, vérifiez :
    1. Si l'utilisateur est authentifié.
    2. S'il a le bon rôle (ex: user.role === 'ADMIN').
    3. Si la ressource manipulée lui appartient (ex: business.ownerId === user.id).
  • Exemple : Si un utilisateur appelle DELETE /api/businesses/123, le serveur doit s'assurer que l'utilisateur qui fait la requête est le propriétaire de la boutique 123 ou un administrateur.

6. Attaques par Déni de Service (DDoS) et Brute Force

La menace : Un attaquant submerge le serveur de requêtes pour le rendre indisponible, ou tente de deviner des mots de passe en envoyant des milliers de requêtes de connexion à la seconde.

Comment corriger :

  • Rate Limiting (Limitation de débit) : Implémentez un Rate Limiter pour bloquer les IP abusives.
    • Utilisez un middleware de limitation (ex: @upstash/ratelimit avec Redis si déployé en serverless, ou un outil proxy inversé comme Nginx / Cloudflare).
  • Pensez à limiter drastiquement les tentatives sur la route /api/auth/login.
  • Mettez en place Cloudflare (ou équivalent) devant votre serveur pour absorber les attaques DDoS massives.

7. Exposition de Données Sensibles (Sensitive Data Exposure)

La menace : Fuite de secrets (clés API, mots de passe de base de données) ou retour de trop d'informations aux clients (ex: renvoyer le mot de passe haché dans la réponse de l'API).

Comment corriger :

  • Fichier .env : Assurez-vous que le fichier .env est bien dans le .gitignore et n'est jamais commité sur GitHub.
  • Select strict dans Prisma : Lorsque vous récupérez un utilisateur, ne renvoyez jamais le mot de passe, même haché.
    const user = await prisma.user.findUnique({
      where: { id: 1 },
      select: { id: true, name: true, email: true, role: true } // Ne sélectionnez PAS 'password'
    });
    

8. En-têtes de Sécurité HTTP

La menace : Les navigateurs web disposent de mécanismes de sécurité natifs qui doivent être activés par le serveur via des en-têtes HTTP. S'ils sont absents, le site s'expose à des attaques comme le Clickjacking ou le reniflage de type MIME.

Comment corriger : Ajoutez les en-têtes de sécurité dans votre fichier next.config.js :

const securityHeaders = [
  { key: 'X-DNS-Prefetch-Control', value: 'on' },
  { key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' }, // Force le HTTPS
  { key: 'X-XSS-Protection', value: '1; mode=block' },
  { key: 'X-Frame-Options', value: 'SAMEORIGIN' }, // Empêche le Clickjacking (le site ne peut pas être mis dans une iframe tierce)
  { key: 'X-Content-Type-Options', value: 'nosniff' },
  { key: 'Referrer-Policy', value: 'origin-when-cross-origin' },
];

module.exports = {
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: securityHeaders,
      },
    ];
  },
};

Résumé et Priorités d'Action

Pour sécuriser Afropreunariat de manière robuste, voici le plan d'action par ordre de priorité :

  1. 🔴 Critique : Sécuriser les XSS. Installez dompurify et nettoyez systématiquement toutes les variables passées dans dangerouslySetInnerHTML.
  2. 🔴 Critique : Sécuriser la session. Ne stockez plus les informations sensibles dans localStorage. Utilisez des cookies HttpOnly ou passez sur une librairie comme NextAuth.js.
  3. 🟠 Haute : Valider les autorisations (IDOR). Passez en revue les Server Actions et API Routes (suppression d'entreprise, modification d'articles) pour s'assurer qu'elles vérifient l'identité et les permissions de l'utilisateur.
  4. 🟡 Moyenne : Configurer next.config.js. Ajoutez les en-têtes de sécurité (Headers HTTP).
  5. 🟡 Moyenne : Rate Limiting. Protégez vos routes d'authentification contre le brute force.