unsecure

Le bug de conception de la PasswordBox

C’est en utilisant la PasswordBox récemment (et en réfléchissant un peu plus que d’habitude) que j’ai réalisé ce que contrôle avait un bug de conception lié à la sécurité.

En WPF, le contrôle expose deux propriétés liées à la gestion du mot de passe.

La propriété SecurePassword est une propriété en readonly qui renvoie le mot de passe stocké par la PasswordBox sous la forme d’une SecureString.

Le type SecureString est un type intéressant qui permet de stocker en mémoire une string de manière sécurisée. Cette chaine de caractères est en effet cryptée en mémoire via DPAPI et ne peut donc être lue en clair malgré le fait qu’elle réside en mémoire.

Pour définir la valeur d’une SecureString il est nécessaire de le remplir caractère par caractère grâce à la méthode AppendChar, et pour lire en clair la valeur stockée par une SecureString on doit allouer de la mémoire et y stocker la valeur en clair de la SecureString via un Marshal.SecureStringToBSTR (qui au passage ne respecte pas les conventions de nommage .net). Une fois lue, on peut ensuite faire un reset la zone mémoire qui contient la valeur en clair via la méthode ZeroFreeBSTR (qui ne respecte toujours pas les conventions de nommage .net).

On réduit ainsi fortement l’intervalle de temps où la chaine de caractères, dans notre cas le mot de passe, est en clair en mémoire.

La PasswordBox utilisant une SecureString en interne on pourrait donc se dire que ce contrôle est parfaitement sécurisé… si l’on évoquait pas la seconde propriété dédiée à la gestion du mot de passe : la propriété Password.

Cette propriété de type String permet de définir et récupérer le mot de passe stocké par la PasswordBox. Et qui dit type String dit, lisible comme de l’eau de roche via n’importe quel outil de type Snoop et consors :

Donc en résumé, la propriété Password devrait en réalité se nommer “UnSecurePassword” et la propriété SecurePassword est inutile. Pourquoi en effet stocker le mot de passe de manière sécurisé si on l’expose en même temps en clair ?

Vous allez me répondre que c’est simple, il faut bien que l’on soit capable de définir la valeur de la PasswordBox via une propriété qui ne soit pas en Readonly. Certes, mais en a-t-on vraiment besoin ?

Le contrôle n’a pour objectif que d’afficher des ●●●●●● et on se moque donc de savoir si les ●●●●●● représente le vrai mot de passe ou en réalité de simples espaces. La classe SecureString exposant une propriété Length on pourrait facilement avoir une représentation visuelle du mot de passe sans avoir à le stocker en clair en mémoire.

On disposerait ainsi d’un contrôle PasswordBox vraiment sécurisé et non pas d’une sécurité en carton.

Quand à l’implémentation d’un tel SecurePasswordBox, il pourrait bien faire l’objet d’un prochain article…

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *