Mass Assignment : comprendre et se protéger
Auteur : Rédaction Domeny.ForSale Publié le
En bref : Mass Assignment désigne l’affectation automatique des données d’une requête HTTP aux champs d’un objet interne ou d’un modèle de base de données. Ce mécanisme devient une faille de sécurité lorsque l’application permet aussi de modifier des champs sur lesquels l’utilisateur ne devrait avoir aucun contrôle, comme son rôle d’administrateur. La protection repose avant tout sur une définition explicite des champs autorisés et sur la vérification des permissions côté serveur.
Comment fonctionne l’affectation automatique des champs
Une application web reçoit les données envoyées par le navigateur, par exemple lors de l’enregistrement d’un profil. Une requête HTTP, c’est-à-dire un message envoyé au serveur, peut contenir un nom d’utilisateur, une adresse e-mail et d’autres valeurs. Le serveur doit ensuite affecter ces valeurs aux champs correspondants dans son code.
Mass Assignment permet de réaliser cette opération en bloc, sans affecter manuellement chaque valeur. Le mécanisme fait correspondre les noms des champs reçus aux propriétés de l’objet. Si les données contiennent un champ nom, sa valeur peut être affectée à la propriété nom de l’objet utilisateur.
Cette mise en correspondance est aussi appelée autobinding. Dans le contexte de cette vulnérabilité, on rencontre également le terme object injection, même s’il peut désigner d’autres mécanismes dans d’autres contextes de sécurité. Le mappage automatique n’est pas une erreur en soi : le problème commence lorsque le serveur accepte davantage de champs qu’il ne devrait.
Exemple simple : modifier un profil et changer de rôle
Supposons que le formulaire de modification du profil permette uniquement de changer le nom affiché et l’adresse e-mail. Les données légitimes envoyées au serveur se présentent ainsi :
{
"nom": "Jean Dupont",
"email": "jean (at) example.com"
}
Dans la base de données, le compte possède toutefois d’autres propriétés. Outre le nom et l’adresse, il contient aussi un champ role qui détermine les permissions de l’utilisateur. Le formulaire ne l’affiche pas, car un utilisateur ordinaire ne devrait pas pouvoir le modifier.
Une personne malveillante n’est cependant pas obligée de passer par le formulaire. Elle peut modifier la requête envoyée et y ajouter un champ :
{
"nom": "Jean Dupont",
"email": "jean (at) example.com",
"role": "administrateur"
}
Si le serveur copie sans restriction toutes les propriétés reçues dans le compte, il peut aussi enregistrer le nouveau rôle. Lorsque le système de permissions s’appuie sur ce champ, l’attaque peut donner accès aux fonctions d’administration.
L’absence d’un champ dans le formulaire n’est pas une protection. C’est au serveur de décider ce qui peut être modifié, et non à la présentation de la page ou au code JavaScript exécuté dans le navigateur.
Quelles données sont particulièrement exposées ?
Mass Assignment ne concerne pas uniquement les comptes utilisateurs. Le risque apparaît partout où des données externes sont automatiquement affectées à des objets qui contiennent aussi des propriétés internes.
Voici quelques exemples de champs qui nécessitent un contrôle particulier :
proprietaire_id— peut déterminer à qui appartient un document ou une commande ;prix— peut influer sur le montant facturé pour un achat ;statut_paiement— peut indiquer si une commande a été payée ;email_confirme— peut permettre de contourner la confirmation de l’adresse.
Par exemple, le client d’une boutique devrait transmettre l’identifiant du produit et la quantité souhaitée. Le serveur devrait déterminer le prix à partir de son propre catalogue, plutôt que d’accepter sans condition la valeur fournie dans la requête.
Tout champ supplémentaire ne conduit pas nécessairement à une attaque. Il doit être accepté, affecté, puis utilisé d’une manière qui a une incidence sur le fonctionnement de l’application. L’analyse doit donc porter sur l’ensemble du parcours des données, et pas seulement sur le contenu du formulaire.
Comment limiter efficacement les risques de Mass Assignment
La protection de base est une liste de champs autorisés : pour une opération donnée, le serveur n’accepte que les propriétés expressément définies par le développeur. Pour une simple modification de profil, il peut s’agir de nom et de email, mais pas de role.
La démarche peut se présenter ainsi :
champs_autorises = ["nom", "email"]
donnees_profil = selectionner_champs(donnees_requete, champs_autorises)
mettre_a_jour_profil(utilisateur_connecte, donnees_profil)
Ce pseudocode illustre le principe ; ce n’est pas une implémentation prête à l’emploi. Selon le framework, les restrictions peuvent être définies dans le mécanisme de mappage, dans un validateur ou dans un objet d’entrée distinct, souvent appelé DTO. Cet objet décrit les données autorisées pour une opération précise, au lieu de reproduire l’intégralité d’un enregistrement de la base.
La validation du format ne suffit pas. La valeur administrateur peut être un nom de rôle valide, sans qu’un utilisateur ordinaire ait pour autant le droit de l’attribuer. Un contrôle d’autorisation est donc également nécessaire : il consiste à vérifier si la personne peut effectuer la modification demandée.
Une liste de champs interdits présente davantage de risques d’oubli : à chaque ajout d’une propriété au modèle, il faut penser à la bloquer. Une liste de champs autorisés, elle, ne rend pas automatiquement les nouvelles propriétés modifiables. Il faut vérifier le comportement exact du framework utilisé et ses protections par défaut dans sa documentation officielle.
Comment vérifier votre propre application
Testez uniquement votre propre système ou un environnement pour lequel vous disposez d’une autorisation. Pour la modification du profil, préparez une requête contenant des données valides, puis ajoutez un champ que l’utilisateur ne devrait pas pouvoir modifier.
Vérifiez non seulement la réponse du serveur, mais aussi les données enregistrées et les permissions effectives du compte. Une implémentation sûre doit rejeter la modification non autorisée ou ignorer le champ supplémentaire sans modifier la valeur protégée.
Commencez par examiner les endroits où l’ensemble des données de la requête est transmis directement aux méthodes de création ou de mise à jour des enregistrements. Pour chacun, consignez les champs autorisés et ajoutez un test confirmant que les autres ne peuvent pas être modifiés.
À lire aussi : Qu’est-ce que Path Traversal ?
