45 votes

Y a-t-il un avantage à utiliser SecureString en ASP.NET ?

Si j'ai bien compris, il s'agit de garder le texte brut hors de la mémoire, afin que l'application soit sécurisée contre les attaques ésotériques sur la mémoire, le tas d'ordures, ou la mémoire paginée sur le disque. La SecureString est alimentée en octets non gérés et consommée un octet non géré à la fois - puis la chaîne est effacée de la mémoire. (Corrigez-moi si je me trompe !)

En ASP.NET, le secret est collecté dans un formulaire web, qui renvoie un message en HTTPS. Mais ensuite, l'objet Request transforme toutes les valeurs de requête du formulaire en paires nom-valeur et les place dans une collection, par exemple Request["TxtPassword"]-- donc avant même que je puisse obtenir la chaîne, elle a déjà été écrite de manière non sécurisée en mémoire. Pire, si j'utilisais un contrôle, alors la représentation non sécurisée aura plus de chaînes gérées dans la propriété du TextBox.

Pour faire quoi que ce soit avec cette SecureString, j'ai besoin d'une API qui accepte les chaînes non gérées. Il semble donc que je ne puisse pas utiliser la chaîne sécurisée pour un paramètre de proc stocké ou pour autre chose.

Est-ce que je m'y prends mal ou est-ce que c'est une erreur d'essayer d'utiliser SecureString sans faire fuir des copies de la chaîne non sécurisée dans la mémoire gérée ?

Passer à OAuth ou Windows auth n'est pas une option.

29voto

Frédéric Hamidi Points 123646

Comme vous l'avez correctement déduit, et comme d'autres l'ont déjà mentionné, il est peu judicieux d'utiliser SecureString pour stocker les données sensibles à la sécurité provenant d'un formulaire ASP.NET, car ces données sont déjà présentes en mémoire en texte clair.

Il existe cependant d'autres scénarios où l'utilisation de SecureString est recommandé, car les données sensibles sont créées par le programme lui-même et ne doivent pas rester en mémoire après qu'il a fini de les utiliser. Par exemple, la création programmatique d'un site SharePoint ou le transfert d'informations d'authentification d'un système à un autre.

Au bon vieux temps, il était plus facile de faire en sorte que la durée de vie des données sensibles soit aussi courte que possible. Elles pouvaient être allouées sur la pile et effacées dès que le programme avait fini de les utiliser :

char secret[512];
generate_secret(secret, sizeof(secret));
do_something_with(secret);
memset(secret, 0, sizeof(secret));
// Secret data is now gone.

Une telle approche n'est cependant pas possible avec les chaînes gérées, principalement pour les raisons suivantes :

  • Ils ne sont pas alloués sur la pile,
  • Ils sont immuables, donc ils ne peuvent pas être effacés,
  • Ils ne sont pas jetables, il n'y a donc aucune garantie quant au moment où le GC libérera les données. Il se peut même qu'elles ne soient jamais libérées, selon les conditions de la mémoire.

SecureString tente de résoudre ce problème en étant mutable et jetable, ce qui permet d'écrire :

using (SecureString secret = new SecureString()) {
    GenerateSecret(secret);
    secret.MakeReadOnly();
    DoSomethingWith(secret);
}
// Secret data is now gone.

7voto

Joel Etherton Points 24155

SecureString est surtout utilisé pour l'attribution d'informations d'identification réseau pour les appels directs entre systèmes. Dans le domaine du Web, il est évident que si l'identifiant est entré par le Web, il est en clair quelque part, mais si vous devez renvoyer cet identifiant par un appel d'identifiant standard (ftp, services d'annuaire, etc.), l'utilisation de SecureString n'est pas une mauvaise méthode de transmission. Même si vous avez raison de dire que la chaîne se trouve déjà sur votre système serveur en texte clair, vous pouvez au moins réduire l'empreinte entre les systèmes. Si vous n'utilisez ce mot de passe que localement, je suis d'accord pour dire que SecureString n'est pas vraiment nécessaire.

En revanche, les bonnes habitudes de sécurité ne sont jamais vraiment une perte de temps.

6voto

Rangoric Points 1853

Je pense que vous en avez l'essentiel. SecureString est conçu du point de vue du client. Donc, pour une application WPF/Winforms (et peut-être Silverlight, je ne me souviens plus si c'est là), cela vaut la peine, mais pour une application côté serveur, cela ne vaut pas la peine, car on n'est pas le premier à traiter la chaîne.

2voto

Casey Points 4095

La seule fois où je signale l'absence d'utilisation de SecureString lors de la réalisation de revues de code sécurisées, sont dans les cas où les données peuvent être cryptées par l'application et réutilisées.

Par exemple, lorsqu'un backend de site web doit communiquer avec une tierce partie ou une autre ressource interne qui nécessite des informations d'identification. Puisque ces informations ne peuvent pas être hachées, j'utiliserais la fonction SecureString lors de l'élaboration de la demande (qui devrait également se faire par TLS).

Une autre alternative est d'utiliser le API de protection des données de Windows si possible.

Notez que le but de SecureString est de garder le contenu en mémoire le moins longtemps possible.

-1voto

David Flamme Points 71

Si je ne me trompe pas, vous pouvez utiliser la solution suivante pour garder l'entrée hors de la gestion des chaînes de caractères du CLR : API Web : comment accéder aux valeurs des formulaires multiparties en utilisant MultipartMemoryStreamProvider ?

Ne lisez les données du formulaire que dans la méthode ExecutePostProcessingAsync(..) comme ReadAsByteArrayAsync() et elles ne devraient jamais devenir des chaînes de caractères en cours de route.

Vous avez toujours besoin de https pour sécuriser l'entrée en cours de route.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X