How do we zero a AnsiString object? For example:
void TesteClass::test()
{
AnsiString cardNumber = "1234567890123456";
..
}
The AnsiString object is destroyed automatically, but its internal data is not cleaned, so a memory acquisition tool can read the information. We need to zero this data to avoid sensitive information be captured in memory.
The AnsiString class has the method c_str()
to access the internal data directly, but doing some like this is not recommended:
memset(cardNumber.c_str(), 0, cardNumber.Length());
What is the correct way to zero the AnsiString internal data before the object is destroyed?
There is nothing wrong with using memset()
like you have shown. Using c_str()
in this manner is correct (as long as you do not exceed the Length()
, since c_str()
returns a pointer to const memory if the AnsiString
is blank):
void TesteClass::test()
{
AnsiString cardNumber = "1234567890123456";
// ...
memset(cardNumber.c_str(), 0, cardNumber.Length());
}
Since you are worried about information leakage, consider using SecureZeroMemory()
instead of memset()
(see What’s the point of SecureZeroMemory?).
To automate the zeroing (so you don't have to remember to do it), consider wrapping the AnsiString
inside an RAII-style class
/struct
(you cannot derive from AnsiString
directly, the RTL does not allow it), whose destructor performs the zeroing, and then use that class
/struct
where needed instead of using AnsiString
directly.
Just be careful, since AnsiString
uses reference-counted data, so don't zero the data unless your AnsiString
is the sole instance referencing the data:
class SaferAnsiString
{
private:
AnsiString m_Str;
void CheckZeroNeeded()
{
// AnsiString gained a public RefCount() method in C++Builder 2009.
// In earlier versions, access the reference count manually...
#ifdef _DELPHI_STRING_UNICODE
if (m_Str.RefCount() == 1)
#else
const void *data = m_Str.data();
if ((data) && (static_cast<const int*>(data)[-2] == 1))
#endif
SecureZeroMemory(m_Str.c_str(), m_Str.Length());
}
public:
SaferAnsiString(const AnsiString &src = AnsiString())
: m_Str(src)
{
}
~SaferAnsiString()
{
CheckZeroNeeded();
}
SaferAnsiString& operator=(const AnsiString &rhs)
{
CheckZeroNeeded();
m_Str = rhs;
return *this;
}
operator AnsiString () const { return m_Str; }
// other methods as needed...
};
void TesteClass::test()
{
SaferAnsiString cardNumber = "1234567890123456";
// ...
}