Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cleanse (overwrite with random bytes) std::string internal buffer?

Consider a scenario, where std::string is used to store a secret. Once it is consumed and is no longer needed, it would be good to cleanse it, i.e overwrite the memory that contained it, thus hiding the secret.

std::string provides a function const char* data() returning a pointer to (since C++11) continous memory.

Now, since the memory is continous and the variable will be destroyed right after the cleanse due to scope end, would it be safe to:

char* modifiable = const_cast<char*>(secretString.data()); OpenSSL_cleanse(modifiable, secretString.size()); 

According to standard quoted here:

$5.2.11/7 - Note: Depending on the type of the object, a write operation through the pointer, lvalue or pointer to data member resulting from a const_cast that casts away a const-qualifier68 may produce undefined behavior (7.1.5.1).

That would advise otherwise, but do the conditions above (continuous, to-be-just-removed) make it safe?

like image 991
hauron Avatar asked Aug 01 '16 15:08

hauron


People also ask

How do I free std::string?

std::string is just a normal class1, so the usual rules apply. If you allocate std::string objects on the stack, as globals, as class members, ... you don't need to do anything special, when they go out of scope their destructor is called, and it takes care of freeing the memory used for the string automatically.

Is std::string dynamically allocated?

Inside every std::string is a dynamically allocated array of char .

How do you change the size of a string in C++?

void string ::resize (size_type num, char c ) num: is the new string length, expressed in number of characters. c: is the character needed to fill the new character space. If num > size() : character c is used to fill space. If num < size() : String is simply resized to num number of characters.

Do I need to free C++ string?

The char* string exists on its own and is unaffected and indeed has its own memory, not shared with the newly created std::string class. You will still need to delete the C-string if it is using malloced memory. Use free for such strings if they are C-style strings created with malloc .


1 Answers

The standard explicitly says you must not write to the const char* returned by data(), so don't do that.

There are perfectly safe ways to get a modifiable pointer instead:

if (secretString.size())   OpenSSL_cleanse(&secretString.front(), secretString.size()); 

Or if the string might have been shrunk already and you want to ensure its entire capacity is wiped:

if (secretString.capacity()) {   secretString.resize(secretString.capacity());   OpenSSL_cleanse(&secretString.front(), secretString.size()); } 
like image 153
Jonathan Wakely Avatar answered Sep 29 '22 14:09

Jonathan Wakely