39 votes

Comment s'assurer que les optimisations du compilateur de ne pas présenter un risque pour la sécurité?

Je dois écrire un service Windows qui gère à un certain point, les données confidentielles (telles que les codes PIN, mots de passe, et ainsi de suite). Ces informations sont nécessaires pour un très court laps de temps: généralement, elles sont envoyées presque immédiatement à un lecteur de carte à puce.

Permet de considérer ce morceau de code:

{
  std::string password = getPassword(); // Get the password from the user

  writePasswordToSmartCard(password);

  // Okay, here we don't need password anymore.
  // We set it all to '\0' so it doesn't stay in memory.
  std::fill(password.begin(), password.end(), '\0');
}

Maintenant mon souci c'est que sur les optimisations du compilateur. Ici, le compilateur peut détecter que le mot de passe est sur le point d'être supprimé et qu'une modification de sa valeur à ce point, est inutile, il suffit de supprimer l'appel.

Je n'attends pas mon compilateur pour se soucier de la valeur de l'avenir-non référencé la mémoire.

Sont mes préoccupations légitimes ? Comment puis-je être sûr que ce morceau de code ne sera pas optimisé-out ?

34voto

sharptooth Points 93379

Oui, vos préoccupations sont légitimes. Vous avez besoin d'utiliser spécialement conçu fonctionner comme SecureZeroMemory() pour éviter les optimisations de la modification de votre code de comportement.

N'oubliez pas que la chaîne de classe aient été spécifiquement conçus pour la manipulation des mots de passe. Par exemple, si la classe de réallouer la mémoire tampon de tenir une longue chaîne qu'il a d'effacer la mémoire tampon avant de retunring à l'allocateur de mémoire. Je ne suis pas sûr, mais il est probable std::string ne le fait pas (au moins par défaut). À l'aide de l'existence d'une chaîne de manutention classe rend l'ensemble de vos préoccupations sans valeur - vous aurez le mot de passe copié dans tout le programme de la mémoire befoe vous savez même.

9voto

ybungalobill Points 31467

Il est problématique, mais pour une autre raison. Qui a dit qu' std::string password = getPassword(); ne pas laisser encore une autre copie dans la mémoire? (Vous avez probablement besoin d'écrire un "secure" allocateur de classe à ce que les zéros de la mémoire sur la "destruction" ou "libérer")

Dans la paix de votre code, vous pouvez éviter d'optimisation par l'obtention d'un volatile pointeur vers la chaîne de données (je ne sais pas si vous pouvez le faire de manière standard), puis zéro les données à travers.

8voto

snemarch Points 3328

Ne pas utiliser std::string pour les mots de passe, car il n'est pas à zéro, c'est la mémoire lorsque vous faites des réaffectations ou la destruction de la conception de votre propre ConfidentialString classe à la place. Lors de la conception de cette classe, vous voudrez peut-être prendre avantage de CryptProtectMemory... et être très, très prudent lorsque vous devez utiliser la version décryptée, en particulier lors de l'appel de code externe.

1voto

JeremyP Points 46808

Dans ce cas précis, je serais vraiment surpris si le compilateur peut optimiser loin d'une invocation de méthode qui pourrait clairement avoir des effets secondaires. Ou est std::remplissez en ligne, de sorte que le compilateur peut voir la mise en œuvre? (Je ne suis pas un programmeur C++).

Ceci dit, ce genre de chose peut être un sujet de préoccupation en général. Mais, vous devez penser à combien il est facile à exploiter. Pour lire la mémoire d'un autre processus, un attaquant aurait besoin d'un certain niveau d'accès administrateur (si non, pourquoi êtes-vous à l'aide de ce système d'exploitation). Si la machine est compromise à ce niveau, vous avez déjà perdu.

0voto

RED SOFT ADAIR Points 5762

Pourquoi ne pas vous venez de désactiver l'optimisation pour le code en question?

#pragma optimize( "", off )

// Code, not to optimize goes here

#pragma optimize( "", on )

Cet exemple de #pragma optimiser est spécifique à MSVC, mais d'autres compilateurs de le soutenir en tant que bien.

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