Aller au contenu principal
Retour au blog

Sécuriser votre app Symfony en 30 minutes : checklist OWASP

Checklist rapide OWASP Top 10 pour Symfony : injection SQL, XSS, CSRF, authentification. Code et config.

Flavien Métivier · 6 min de lecture
Sommaire · 7 parties

La sécurité n'est pas un luxe réservé aux grandes équipes. Avec Symfony, 80 % de la protection est déjà intégrée au framework. Encore faut-il l'activer correctement. Voici une checklist rapide basée sur l'OWASP Top 10 — chaque point est vérifiable en quelques minutes.

A01 — Broken Access Control : les Voters

Symfony protège les routes avec access_control dans security.yaml. Mais le contrôle d'accès granulaire — « cet utilisateur peut-il modifier cette ressource ? » — nécessite des Voters.

php
<?php

declare(strict_types=1);

// Dans le controller : une seule ligne
#[Route('/{id}', methods: ['DELETE'])]
public function delete(User $user): Response
{
    $this->denyAccessUnlessGranted('USER_DELETE', $user);
    // Si le Voter refuse, Symfony renvoie automatiquement un 403
}

// Le Voter centralise la logique d'accès
final class UserVoter extends Voter
{
    protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
    {
        $currentUser = $token->getUser();
        return match ($attribute) {
            'USER_DELETE' => $this->security->isGranted('ROLE_ADMIN')
                && !$subject->id()->equals($currentUser->id()),
            default => false,
        };
    }
}

A02 — Cryptographic Failures : password hashing

Symfony gère le hashing automatiquement via le composant Security. Il suffit de configurer l'algorithme :

yaml
# config/packages/security.yaml
security:
    password_hashers:
        Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
            algorithm: auto    # Utilise bcrypt ou argon2 selon la plateforme
            cost: 15           # Minimum recommandé (bcrypt)

    # Forcer HTTPS partout
    access_control:
        - { path: ^/, roles: PUBLIC_ACCESS, requires_channel: https }

A03 — Injection SQL : Doctrine vous protège (si vous l'utilisez correctement)

Doctrine paramètre automatiquement les requêtes via le QueryBuilder. La seule erreur à éviter : la concaténation de chaînes dans les requêtes DQL ou SQL brutes.

php
<?php

// INTERDIT — injection SQL possible
$dql = "SELECT u FROM User u WHERE u.email = '$email'";

// OBLIGATOIRE — paramètre sécurisé
$qb = $this->createQueryBuilder('u')
    ->where('u.email = :email')
    ->setParameter('email', $email->toString())
    ->getQuery()
    ->getOneOrNullResult();

A04 — Insecure Design : validation des inputs

Chaque donnée entrante doit être validée avec le composant Validator de Symfony. Utilisez des DTOs avec des contraintes PHP 8 Attributes :

Migration Symfony en vue ?

Bear Upgrade migre votre codebase 2,5× à 4,5× moins cher qu'une ESN, selon sa maturité.

Estimer ma migration →
php
<?php

declare(strict_types=1);

use Symfony\Component\Validator\Constraints as Assert;

final readonly class CreateUserDTO
{
    public function __construct(
        #[Assert\NotBlank]
        #[Assert\Email(mode: 'strict')]
        #[Assert\Length(max: 180)]
        public string $email,

        #[Assert\NotBlank]
        #[Assert\Length(min: 12, max: 4096)]
        #[Assert\NotCompromisedPassword]
        #[Assert\PasswordStrength(minScore: Assert\PasswordStrength::STRENGTH_STRONG)]
        public string $password,
    ) {}
}

A05 — Security Misconfiguration : headers et sessions

Ajoutez un event listener qui injecte les headers de sécurité sur chaque réponse :

php
<?php

declare(strict_types=1);

use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpKernel\Event\ResponseEvent;

#[AsEventListener(event: 'kernel.response')]
final readonly class SecurityHeadersListener
{
    public function __invoke(ResponseEvent $event): void
    {
        if (!$event->isMainRequest()) { return; }

        $headers = $event->getResponse()->headers;
        $headers->set('X-Frame-Options', 'DENY');
        $headers->set('X-Content-Type-Options', 'nosniff');
        $headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');
        $headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
        $headers->set('Content-Security-Policy', "default-src 'self'");
    }
}

A07 — Authentication Failures : rate limiting

Symfony intègre un composant RateLimiter depuis la version 5.2. Configurez-le pour protéger vos endpoints sensibles :

yaml
# config/packages/framework.yaml
framework:
    rate_limiter:
        login:
            policy: 'sliding_window'
            limit: 5
            interval: '15 minutes'
        api:
            policy: 'token_bucket'
            limit: 1000
            rate: { interval: '1 hour' }

La checklist complète en 30 minutes

  • Vérifier que tous les endpoints sensibles ont un Voter (5 min)
  • Vérifier security.yaml : password_hashers, HTTPS, CSRF (3 min)
  • Rechercher les requêtes SQL/DQL sans setParameter (5 min)
  • Vérifier que chaque DTO entrant a des contraintes Assert (5 min)
  • Ajouter le SecurityHeadersListener si absent (3 min)
  • Configurer le rate limiting sur login et API (3 min)
  • Lancer composer audit pour les CVE (1 min)
  • Vérifier les sessions : cookie_secure, cookie_httponly, cookie_samesite (2 min)
  • Vérifier le logging sécurité dans Monolog (3 min)

Cette checklist couvre les fondamentaux. Pour un audit de sécurité complet avec scoring et roadmap chiffrée, notre service Bear Scan analyse votre codebase sur les 10 risques OWASP avec des recommandations actionnables. En savoir plus.

Cet article vous a été utile ? Partagez-le.

Portrait de Flavien Métivier, fondateur de The Bearded Bear : barbe longue, lunettes, sur fond sombre

Écrit par

Flavien Métivier

Expert PHP/Symfony indépendant depuis 2014, ancien CTO de Kartable et d'Extrabat. Plus de 80 projets menés, de l'audit à la migration.

Mon parcours

À lire ensuite

Migration Symfony en vue ?

Bear Upgrade migre votre codebase 2,5× à 4,5× moins cher qu'une ESN, selon sa maturité.

Newsletter Bear Bytes

Veille Claude Code, Symfony et PHP, retours d'expérience terrain et conseils techniques, directement dans votre boîte mail.