Aller au contenu principal

Sécuriser son application web : le guide OWASP 2025

Les 10 vulnérabilités web critiques selon l'OWASP et leurs solutions concrètes. Protégez votre entreprise des cyberattaques avec ce guide pratique validé par des experts.

Sécuriser son application web : le guide OWASP 2025

La cybersécurité n'est plus optionnelle pour les PME belges. **73% d'entre elles ont subi au moins une tentative de cyberattaque en 2024**. Ce guide décrypte les 10 vulnérabilités critiques identifiées par l'OWASP et vous montre comment protéger efficacement votre application web.

Comprendre l'OWASP Top 10

L'**OWASP (Open Web Application Security Project)** est une organisation à but non lucratif qui publie tous les 3-4 ans une liste des vulnérabilités web les plus critiques. Ces 10 failles représentent **80% des incidents de sécurité** recensés dans les applications web.

Pourquoi c'est crucial pour votre entreprise

  • **Conformité RGPD** : Une faille exposant des données personnelles peut coûter jusqu'à 4% de votre chiffre d'affaires
  • **Réputation** : 60% des clients perdent confiance après une fuite de données
  • **Coût financier** : Le coût moyen d'une cyberattaque pour une PME belge s'élève à **85 000€**

Injection SQL, NoSQL et Command

L'injection permet à un attaquant d'exécuter du code malveillant dans votre base de données ou votre système.

Exemple de code vulnérable

// ❌ DANGEREUX - Injection SQL possible
const email = req.body.email;
const query = `SELECT * FROM users WHERE email = '${email}'`;
db.query(query);

Un attaquant peut injecter : `admin@site.com' OR '1'='1` et accéder à tous les comptes.

Solution : Requêtes préparées

// ✅ SÉCURISÉ - Paramètres échappés automatiquement
const email = req.body.email;
const query = 'SELECT * FROM users WHERE email = $1';
const result = await db.query(query, [email]);

Avec un ORM moderne (Prisma)

// ✅ SÉCURISÉ - Protection intégrée
const user = await prisma.user.findUnique({
  where: { email: email } // Échappement automatique
});

Authentification cassée

Des mécanismes d'authentification faibles ouvrent la porte aux attaques : sessions non expirées, mots de passe faibles, absence de 2FA.

1. Implémenter NextAuth.js

// app/api/auth/[...nextauth]/route.ts
import NextAuth from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';
import CredentialsProvider from 'next-auth/providers/credentials';

export const authOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
    CredentialsProvider({
      async authorize(credentials) {
        // Vérification sécurisée
        const user = await verifyUser(credentials);
        return user || null;
      }
    })
  ],
  session: {
    strategy: 'jwt',
    maxAge: 24 * 60 * 60, // 24 heures
  },
  pages: {
    signIn: '/login',
    error: '/auth/error',
  },
};

export default NextAuth(authOptions);

2. Hash sécurisé avec bcrypt

import bcrypt from 'bcryptjs';

// Enregistrement d'un utilisateur
async function registerUser(email: string, password: string) {
  const saltRounds = 12; // Coût computationnel élevé
  const hashedPassword = await bcrypt.hash(password, saltRounds);

  await db.user.create({
    data: { email, password: hashedPassword }
  });
}

// Vérification lors du login
async function verifyUser(email: string, password: string) {
  const user = await db.user.findUnique({ where: { email } });
  if (!user) return null;

  const isValid = await bcrypt.compare(password, user.password);
  return isValid ? user : null;
}

3. Rate limiting sur les endpoints sensibles

import { Ratelimit } from '@upstash/ratelimit';
import { Redis } from '@upstash/redis';

const ratelimit = new Ratelimit({
  redis: Redis.fromEnv(),
  limiter: Ratelimit.slidingWindow(5, '15 m'), // 5 tentatives / 15 min
});

export async function POST(request: Request) {
  const ip = request.headers.get('x-forwarded-for') ?? 'unknown';
  const { success } = await ratelimit.limit(ip);

  if (!success) {
    return Response.json(
      { error: 'Trop de tentatives, réessayez dans 15 minutes' },
      { status: 429 }
    );
  }

  // Traitement de la requête...
}

Exposition de données sensibles

Les données sensibles doivent être chiffrées en transit (HTTPS) et au repos.

Configuration HTTPS stricte

// next.config.ts
export default {
  async headers() {
    return [
      {
        source: '/:path*',
        headers: [
          {
            key: 'Strict-Transport-Security',
            value: 'max-age=63072000; includeSubDomains; preload'
          },
          {
            key: 'X-Content-Type-Options',
            value: 'nosniff'
          },
          {
            key: 'X-Frame-Options',
            value: 'DENY'
          },
          {
            key: 'X-XSS-Protection',
            value: '1; mode=block'
          }
        ],
      },
    ];
  },
};

Gestion sécurisée des secrets

# .env.local - JAMAIS commité dans Git
DATABASE_URL="postgresql://user:password@localhost:5432/db"
JWT_SECRET="votre-secret-aleatoire-de-32-caracteres-minimum"
STRIPE_SECRET_KEY="sk_live_..."

Validation des variables d'environnement

// lib/env.ts
import { z } from 'zod';

const envSchema = z.object({
  DATABASE_URL: z.string().url(),
  JWT_SECRET: z.string().min(32),
  STRIPE_SECRET_KEY: z.string().startsWith('sk_'),
});

export const env = envSchema.parse(process.env);

Cross-Site Scripting (XSS)

Le XSS permet d'injecter du JavaScript malveillant dans vos pages web.

Protection native de React

// ✅ SÉCURISÉ - React échappe automatiquement
function UserProfile({ username }) {
  return <h1>Bienvenue {username}</h1>;
}

Attention au HTML brut

// ❌ DANGEREUX
function RichContent({ html }) {
  return <div dangerouslySetInnerHTML={{ __html: html }} />;
}

// ✅ SÉCURISÉ - Nettoyage préalable
import DOMPurify from 'isomorphic-dompurify';

function RichContent({ html }) {
  const cleanHTML = DOMPurify.sanitize(html, {
    ALLOWED_TAGS: ['p', 'b', 'i', 'em', 'strong', 'a'],
    ALLOWED_ATTR: ['href']
  });

  return <div dangerouslySetInnerHTML={{ __html: cleanHTML }} />;
}

Cross-Site Request Forgery (CSRF)

Le CSRF force un utilisateur authentifié à exécuter des actions non désirées.

Protection avec middleware Next.js

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  // Vérifier l'origine des requêtes
  const origin = request.headers.get('origin');
  const host = request.headers.get('host');

  if (request.method !== 'GET') {
    if (!origin || !origin.includes(host!)) {
      return new NextResponse('Forbidden', { status: 403 });
    }
  }

  return NextResponse.next();
}

export const config = {
  matcher: '/api/:path*',
};

Checklist de sécurité par niveau

Niveau 1 : Essentiel (obligatoire)

  • ✓ HTTPS activé avec HSTS
  • ✓ Mots de passe hashés (bcrypt avec salt >= 12)
  • ✓ Requêtes SQL préparées ou ORM
  • ✓ Variables d'environnement sécurisées (.env.local)
  • ✓ Headers de sécurité configurés
  • ✓ Dépendances à jour (npm audit)

Niveau 2 : Recommandé

  • ✓ Authentification à deux facteurs (2FA)
  • ✓ Rate limiting sur toutes les API
  • ✓ Logs d'audit avec rotation
  • ✓ Monitoring d'erreurs (Sentry, LogRocket)
  • ✓ Backups quotidiens automatiques et chiffrés
  • ✓ CSP (Content Security Policy) strict

Niveau 3 : Avancé

  • ✓ Tests SAST/DAST en CI/CD
  • ✓ Audit automatique des dépendances (Dependabot)
  • ✓ WAF (Web Application Firewall)
  • ✓ Pentest annuel par un tiers de confiance
  • ✓ Plan de réponse aux incidents documenté et testé

Outils recommandés

**SAST (Static Application Security Testing)**

  • Snyk - Scan de dépendances vulnérables
  • SonarQube - Analyse de code statique

**DAST (Dynamic Application Security Testing)**

  • OWASP ZAP - Scanner de vulnérabilités web
  • Burp Suite - Tests de pénétration avancés

**Monitoring & Alerting**

  • Sentry - Tracking d'erreurs en temps réel
  • LogRocket - Session replay pour détecter les abus

**Validation**

  • SecurityHeaders.com - Vérifier vos headers HTTP
  • SSL Labs - Tester votre configuration HTTPS

**Besoin d'un audit de sécurité ?** Smidjan propose des audits OWASP complets pour identifier et corriger les failles de votre application web.

Besoin d'accompagnement ?

Smidjan vous aide à mettre en place ces solutions pour votre entreprise en Belgique.

Discutons de votre projet →