Considérations sur la sécurité (Entity Framework)
Cet article décrit les considérations relatives à la sécurité propres au développement, au déploiement et à l’exécution d’applications Entity Framework. Vous devez également suivre ces recommandations pour créer des applications .NET Framework sécurisées. Pour plus d’informations, consultez Vue d’ensemble de la sécurité.
Considérations générales sur la sécurité
Les considérations relatives à la sécurité ci-dessous s'appliquent à toutes les applications qui utilisent Entity Framework.
Utilisez uniquement des fournisseurs de sources de données approuvés
Pour communiquer avec la source de données, un fournisseur doit effectuer les opérations suivantes :
- Recevez la chaîne de connexion d’Entity Framework ;
- traduire l’arborescence de commandes en langage de requête natif de la source de données ;
- assembler et retourner des jeux de résultats.
Pendant l'opération d'ouverture de session, les informations qui sont basées sur le mot de passe de l'utilisateur sont passées au serveur via bibliothèques réseau de la source de données sous-jacente. Un fournisseur malveillant peut voler les informations d'identification de l'utilisateur, générer des requêtes malveillantes ou falsifier le jeu de résultats.
Chiffrez votre connexion pour protéger les données sensibles
Entity Framework ne gère pas directement le chiffrement des données. Si les utilisateurs accèdent aux données via un réseau public, votre application doit établir une connexion chiffrée à la source de données pour augmenter la sécurité. Pour plus d'informations, voir la documentation relative à la sécurité pour votre source de données.
Sécurisez la chaîne de connexion
La protection de l'accès à votre source de données représente l'un de vos principaux objectifs lorsque vous sécurisez une application. Une chaîne de connexion présente une vulnérabilité potentielle si elle n'est pas sécurisée ou si elle n'est pas correctement construite. Lorsque vous stockez les informations de connexion au format texte brut ou que vous les conservez dans la mémoire, vous risquez de compromettre l'ensemble de votre système. Les méthodes recommandées pour sécuriser des chaînes de connexion sont les suivantes :
Utilisez les identités managées pour les ressources Azure lorsque vous vous connectez à Azure SQL.
Pour en savoir plus, veuillez consulter Identités managées pour les ressources Azure.
Utilisez l'authentification Windows avec une source de données SQL Server locale.
Lorsque vous utilisez l'authentification Windows pour vous connecter à une source de données SQL Server, la chaîne de connexion ne contient pas d'informations d'ouverture de session et de mot de passe.
Chiffrez les sections du fichier de configuration à l'aide d'une configuration protégée.
ASP.NET fournit une nouvelle fonctionnalité, appelée « configuration protégée », qui vous permet de chiffrer les informations sensibles dans un fichier de configuration. Bien qu'elle ait été conçue à l'origine pour ASP.NET, vous pouvez utiliser la configuration protégée pour chiffrer les sections des fichiers de configuration dans des applications Windows.
Stockez les chaînes de connexion dans des fichiers de configuration sécurisés.
Vous ne devez jamais incorporer des chaînes de connexion dans votre code source. Vous pouvez stocker des chaînes de connexion dans des fichiers de configuration, ce qui évite d'avoir à les incorporer dans le code de votre application. Par défaut, l'Assistant EDM stocke les chaînes de connexion dans le fichier de configuration de l'application. Vous devez sécuriser ce fichier pour empêcher l'accès non autorisé.
Utilisez des générateurs de chaînes de connexion lors de la création dynamique de connexions.
Si vous devez construire des chaînes de connexion au moment de l’exécution, utilisez la classe EntityConnectionStringBuilder. Cette classe du générateur de chaînes permet d'empêcher les attaques par injection de chaîne de connexion en validant et en plaçant dans une séquence d'échappement les informations d'entrée non valides. Utilisez également la classe du générateur de chaînes appropriée pour construire la chaîne de connexion à la source de données qui fait partie de la chaîne de connexion Entity Framework. Pour plus d’informations sur les générateurs de chaînes de connexion pour les fournisseurs ADO.NET, consultez Générateurs de chaînes de connexion.
Pour plus d’informations, consultez Protection des informations de connexion.
N'exposez pas un EntityConnection à des utilisateurs non approuvés
Un objet EntityConnection expose la chaîne de connexion de la connexion sous-jacente. Un utilisateur ayant accès à un objet EntityConnection peut également modifier l'objet ConnectionState de la connexion sous-jacente. La classe EntityConnection n'est pas thread-safe.
Ne passez pas de connexions à l'extérieur du contexte de sécurité
Après avoir établi une connexion, vous ne devez pas la passer à l'extérieur du contexte de sécurité. Par exemple, un thread bénéficiant de l'autorisation nécessaire pour ouvrir une connexion ne doit pas stocker la connexion dans un emplacement global. Si la connexion est disponible dans un emplacement global, un autre thread malveillant peut utiliser la connexion ouverte sans que cette autorisation lui soit explicitement accordée.
Gardez à l'esprit que les informations de connexion et les mots de passe peuvent être visibles dans un vidage de la mémoire
Lorsque les informations d’ouverture de session et de mot de passe de la source de données sont fournies dans la chaîne de connexion, ces informations sont conservées en mémoire jusqu’à ce que le garbage collection récupère les ressources. Il est par conséquent impossible de déterminer quand une chaîne de mot de passe n'est plus en mémoire. Si une application se bloque, un fichier de vidage de la mémoire peut contenir des informations sensibles sur la sécurité, et l'utilisateur qui exécute l'application ainsi que tout utilisateur disposant d'un accès en tant qu'administrateur à l'ordinateur peuvent consulter le fichier de vidage de la mémoire. Utilisez l'authentification Windows pour les connexions à Microsoft SQL Server.
Accordez aux utilisateurs uniquement les autorisations nécessaires dans la source de données
Un administrateur de source de données doit accorder uniquement les autorisations nécessaires aux utilisateurs. Même si Entity SQL ne prend pas en charge les instructions DML qui modifient les données, telles qu’INSERT, UPDATE ou DELETE, les utilisateurs peuvent néanmoins accéder à la connexion à la source de données. Un utilisateur malveillant pourrait utiliser cette connexion pour exécuter des instructions DML dans le langage natif de la source de données.
Exécutez les applications avec les autorisations minimales
Quand vous permettez à une application managée de s’exécuter avec une autorisation de confiance totale, le .NET Framework ne limite pas l’accès de l’application à votre ordinateur. De ce fait, une faille de sécurité dans votre application risque de compromettre l'ensemble de votre système. Pour utiliser la sécurité d’accès du code et d’autres mécanismes de sécurité dans le .NET Framework, vous devez exécuter les applications en utilisant des autorisations de confiance partielle et avec l’ensemble minimal des autorisations qui sont requises pour permettre à l’application de fonctionner. Les autorisations d’accès au code suivantes sont les autorisations minimales requises par votre application Entity Framework :
FileIOPermission : Write pour ouvrir les fichiers de métadonnées spécifiés ou PathDiscovery pour rechercher des fichiers de métadonnées dans un répertoire.
ReflectionPermission : RestrictedMemberAccess pour prendre en charge des requêtes LINQ to Entities.
DistributedTransactionPermission: Unrestricted pour s'inscrire dans un objet System.TransactionsTransaction.
SecurityPermission : SerializationFormatter pour sérialiser des exceptions à l'aide de l'interface ISerializable.
Autorisation d’ouvrir une connexion de base de données et d’exécuter des commandes sur la base de données, telle que SqlClientPermission pour une base de données SQL Server.
Pour plus d'informations, consultez Code Access Security and ADO.NET.
N'installez pas d'applications non approuvées
Entity Framework n'applique aucune autorisation de sécurité et appelle tout le code d'objet de données fourni par l'utilisateur en cours de traitement, qu'il soit approuvé ou non. Assurez-vous que l'authentification et l'autorisation du client sont effectuées par la banque de données et par votre application.
Limitez l'accès à tous les fichiers de configuration
Un administrateur doit limiter l’accès en écriture à tous les fichiers qui spécifient la configuration d’une application, y compris à enterprisesec.config, à security.config, à machine.conf et au fichier de configuration de l’application <application>.exe.config.
Le nom invariant du fournisseur est modifiable dans le fichier app.config. L’application cliente doit prendre la responsabilité de l’accès au fournisseur sous-jacent via le modèle Factory du fournisseur standard en utilisant un nom fort.
Limitez les autorisations aux fichiers de modèle et de mappage
Un administrateur doit limiter l'accès en écriture aux fichiers de modèle et de mappage (.edmx, .csdl, .ssdl et .msl) uniquement aux utilisateurs qui modifient le modèle ou les mappages. Entity Framework nécessite uniquement l’accès en lecture à ces fichiers au moment de l’exécution. Un administrateur doit également limiter l’accès aux fichiers de couche objet et aux fichiers de code source de vue précompilés qui sont générés par les outils Entity Data Model.
Considérations sur la sécurité pour les requêtes
Vous devez tenir compte des considérations sur la sécurité suivantes lors de l'interrogation d'un modèle conceptuel. Ces considérations s’appliquent aux requêtes Entity SQL utilisant EntityClient et aux requêtes d’objet utilisant LINQ, Entity SQL et les méthodes du Générateur de requêtes.
Empêchez les attaques par injection de code SQL
Les applications reçoivent fréquemment des entrées externes (provenant d'un utilisateur ou d'un autre agent externe) et exécutent des actions en fonction de ces entrées. Toute entrée qui provient directement ou indirectement d'un utilisateur ou d'un agent externe doit avoir un contenu qui utilise la syntaxe du langage cible afin d'exécuter des actions non autorisées. Quand le langage cible est un langage SQL, tel que Transact-SQL, cette manipulation est appelée « attaque par injection de code SQL ». Un utilisateur malveillant peut injecter des commandes directement dans la requête et déposer une table de base de données, provoquer un déni de service ou modifier d’une manière ou d’une autre la nature de l’opération en cours.
Attaques par injection dans Entity SQL :
Les attaques par injection de code SQL peuvent être effectuées dans Entity SQL en fournissant une entrée malveillante à des valeurs qui sont utilisées dans un prédicat de requête et dans les noms de paramètres. Pour éviter le risque d’injection de code SQL, vous ne devez jamais associer une entrée d’utilisateur à un texte de commande Entity SQL.
Les requêtes Entity SQL acceptent des paramètres partout où des littéraux sont admis. Vous devez utiliser des requêtes paramétrables plutôt que d'injecter des littéraux directement dans la requête à partir d'un agent externe. Vous devez également envisager d’utiliser les méthodes du Générateur de requêtes pour construire sans risque Entity SQL.
Attaques par injection dans LINQ to Entities :
Même s’il est possible de composer des requêtes dans LINQ to Entities, cette opération est effectuée via l’API de modèle objet. Contrairement aux requêtes Entity SQL, les requêtes LINQ to Entities ne sont pas composées par manipulation ou concaténation de chaînes, et elles ne sont pas sujettes à des attaques par injection de code SQL au sens classique du terme.
Évitez les jeux de résultats très volumineux
Un jeu de résultats très volumineux pourrait entraîner l'arrêt du système client si le client effectue des opérations qui consomment des ressources proportionnelles à la taille du jeu de résultats. Les jeux de résultats volumineux inattendus peuvent se produire dans les conditions suivantes :
- dans les requêtes qui n'incluent pas de conditions de filtre appropriées sur une base de données volumineuse ;
- dans les requêtes qui créent des jointures cartésiennes sur le serveur ;
- dans les requêtes Entity SQL imbriquées.
Lorsque vous acceptez une entrée d'utilisateur, vous devez vous assurer que l'entrée ne peut pas générer des jeux de résultats plus volumineux que ce que le système peut gérer. Vous pouvez également utiliser la méthode Take dans LINQ to Entities ou l’opérateur LIMIT dans Entity SQL pour limiter la taille du jeu de résultats.
Évitez de retourner les résultats IQueryable lors de l'exposition de méthodes à des appelants potentiellement non fiables
Évitez de retourner des types IQueryable<T> des méthodes exposées aux appelants potentiellement non fiables pour les raisons suivantes :
Le consommateur d'une requête qui expose un type IQueryable<T> pourrait appeler des méthodes qui exposent des données sécurisées ou augmentent la taille du jeu de résultats. Par exemple, considérez la signature de méthode suivante :
public IQueryable<Customer> GetCustomer(int customerId)
Un consommateur de cette requête pourrait appeler
.Include("Orders")
sur leIQueryable<Customer>
retourné pour récupérer des données que la requête ne projette pas d'exposer. Cela peut être évité en modifiant le type de retour de la méthode en IEnumerable<T> et en appelant une méthode (telle que.ToList()
) qui matérialise les résultats.Parce que les requêtes IQueryable<T> sont exécutées lorsque les résultats sont itérés, le consommateur d'une requête qui expose un type IQueryable<T> pourrait intercepter des exceptions levées. Les exceptions pourraient contenir des informations non prévues pour le consommateur.
Considérations sur la sécurité pour les entités
Les considérations sur la sécurité suivantes s'appliquent lors de la génération et l'utilisation de types d'entités.
Ne partagez pas un ObjectContext entre des domaines d'application
Le partage d'un objet ObjectContext avec plusieurs domaines d'application peut exposer des informations dans la chaîne de connexion. Il est préférable de transférer les objets sérialisés ou les graphiques d'objets à l'autre domaine d'application, puis d'attacher ces objets à un objet ObjectContext dans ce domaine d'application. Pour plus d’informations, consultez Sérialisation d’objets.
Évitez les violations de la cohérence des types
Si la cohérence des types n'est pas respectée, Entity Framework ne peut pas garantir l'intégrité des données dans les objets. Les violations de la cohérence des types peuvent se produire si vous permettez à des applications non approuvées de s'exécuter avec une sécurité d'accès du code d'un niveau de confiance totale.
Gérer les exceptions
Accédez aux méthodes et aux propriétés d'un ObjectContext dans un bloc try-catch. L'interception d'exceptions empêche des exceptions non gérées d'exposer aux utilisateurs de votre application des entrées dans ObjectStateManager ou dans les informations de modèle (telles que les noms de tables).
Considérations sur la sécurité pour les applications ASP.NET
Vous devez prendre en compte les éléments suivants quand vous utilisez des chemins dans des applications ASP.NET.
Vérifiez si votre hôte effectue des contrôles de chemin d’accès
Quand la chaîne de la substitution |DataDirectory|
(placées entre barres verticales) est utilisée, ADO.NET vérifie que le chemin résolu est pris en charge. Par exemple, « .. » n'est pas autorisé derrière DataDirectory
. Le même contrôle est effectué par le processus qui héberge ASP.NET pour résoudre l’opérateur de racine de l’application web (~
). IIS effectue ce contrôle ; toutefois, les hôtes autres qu'IIS ne peuvent pas vérifier que le chemin d'accès résolu est pris en charge. Vous devez connaître le comportement de l’hôte sur lequel vous déployez une application Entity Framework.
Ne faites pas de suppositions sur les noms de chemins d’accès résolus
Bien que les valeurs auxquelles l'opérateur racine (~
) et la chaîne de la substitution DataDirectory
correspondent doivent rester constantes pendant l'exécution de l'application, Entity Framework n'empêche pas l'hôte de modifier ces valeurs.
Vérifiez la longueur du chemin d’accès avant le déploiement
Avant de déployer une application Entity Framework, vous devez vous assurer que les valeurs de l’opérateur racine (~) et de la chaîne de substitution DataDirectory
ne dépassent pas les limites de longueur de chemin du système d’exploitation. Les fournisseurs de données ADO.NET ne garantissent pas que la longueur du chemin respecte les limites valides.
Considérations sur la sécurité pour les métadonnées ADO.NET
Les considérations sur la sécurité suivantes s'appliquent lors de la génération et de l'utilisation de fichiers de modèle et de mappage.
N'exposez pas d'informations sensibles via la journalisation
Les composants du service de métadonnées ADO.NET n’enregistrent aucune information personnelle. Si des résultats ne peuvent pas être retournés à cause de restrictions d'accès, les systèmes de gestion de base de données et les systèmes de fichiers doivent retourner zéro résultat au lieu de lever une exception qui pourrait contenir des informations sensibles.
N'acceptez pas d'objets MetadataWorkspace provenant de sources non fiables
Les applications ne doivent pas accepter les instances de la classe MetadataWorkspace provenant de sources non fiables. Il est préférable de construire et de remplir explicitement un espace de travail à partir d'une telle source.