Dans les applications Laravel multi-mandants, le scope global est l’outil de choix : chaque requête d’un modèle reçoit automatiquement la condition du mandant actuel. Cela protège bien la lecture. Trois endroits y échappent pourtant.
1. Validation avec exists et unique
Les règles exists et unique interrogent directement la base de données, sans Eloquent. Un formulaire peut ainsi renvoyer à un enregistrement d’un autre mandant sans que la validation ne signale d’erreur. Remède : une règle propre qui vérifie toujours le mandant — et un test qui essaie avec un identifiant étranger.
2. Modèles sans scope
Un contexte de mandant défini n’est pas un filtre si le modèle ne porte pas le scope — souvent le modèle des utilisateurs. Qui demande « tous les utilisateurs de cette entreprise » obtient alors tous les utilisateurs. Remède : placer les exceptions dans un scope nommé et toujours tester les listes avec un second mandant qui ne doit rien recevoir.
3. Ordre des middlewares
Si la liaison des routes s’exécute avant le middleware qui définit le mandant, Laravel trouve des enregistrements étrangers et la policy répond 403 au lieu de 404. Cela seul révèle que l’enregistrement existe. Remède : placer le mandant avant la liaison grâce à la priorité des middlewares et tester « étranger donne 404 » dans chaque module.
Point commun des trois cas : un test avec un seul mandant ne voit aucune fuite. Seul le second mandant la rend visible.