Jump to content
A.M. Hoornweg

FastMM4 and option "AlwaysClearFreedMemory"

Recommended Posts

Hello all,

 

I'd like to know if it is possible to activate the FastMM4 Option "AlwaysClearFreedMemory" temporarily/on demand in code? 

The reason being that some of my routines work with confidential passwords/hashes.  Delphi often uses temporary "hidden" strings and interfaces (for example when concatenating strings) so there's the risk of legible stuff remaining in RAM when such a routine exits.  

Share this post


Link to post

Just control the copies carefully. Everything Delphi does with strings could be imitated with manually allocated buffers that are cleaned manually.

Edited by Fr0sT.Brutal

Share this post


Link to post
1 hour ago, A.M. Hoornweg said:

Hello all,

 

I'd like to know if it is possible to activate the FastMM4 Option "AlwaysClearFreedMemory" temporarily/on demand in code? 

The reason being that some of my routines work with confidential passwords/hashes.  Delphi often uses temporary "hidden" strings and interfaces (for example when concatenating strings) so there's the risk of legible stuff remaining in RAM when such a routine exits.  

That's surely not the right solution to the problem. The right solution is to implement the critical code following standard security practices.  And to then get it audited by a security expert.

Edited by David Heffernan
  • Like 1

Share this post


Link to post
3 hours ago, A.M. Hoornweg said:

I'd like to know if it is possible to activate the FastMM4 Option "AlwaysClearFreedMemory" temporarily/on demand in code? 

No, it is not, because AlwaysClearFreedMemory is a compile-time {$define}, not a runtime variable (like ReportMemoryLeaksOnShutdown is, for instance).  It is processed only when FastMM4.pas is being compiled.

 

There was a feature request made 2 years ago asking for AlwaysClearFreedMemory to be configurable at runtime.  It is still open:

#51 Feature request regarding option "AlwaysClearFreedMemory"

Quote

The reason being that some of my routines work with confidential passwords/hashes.  Delphi often uses temporary "hidden" strings and interfaces (for example when concatenating strings) so there's the risk of legible stuff remaining in RAM when such a routine exits.  

Then don't do such things on strings/interfaces containing sensitive data.  And do use things like the CryptProtectMemory(), CryptUnprotectData(), and SecureZeroMemory() functions to secure the sensitive data in memory while you are not actively using it.

Edited by Remy Lebeau

Share this post


Link to post
On 3/27/2020 at 7:02 PM, Remy Lebeau said:

Then don't do such things on strings/interfaces containing sensitive data.  And do use things like the CryptProtectMemory(), CryptUnprotectData(), and SecureZeroMemory() functions to secure the sensitive data in memory while you are not actively using it.

My application needs to call sp_setapprole on MS SQL Server which requires a user name and password.  So for a brief time I need these in cleartext form. 

 

They are currently stored in an AES encrypted file and I decrypt them on the fly when I need them, using Turbopower Lockbox 2.09.  I have no way of knowing if its decryption engine leaves any decoded text in freed blocks on the heap so I thought it would be great if I could simply instruct the heap manager to wipe whatever memory is released. This would prevent the password from appearing in a memory dump.

 

Edit: The actual SQL Query is executed using

connection.execute(format('exec sp_setapprole ''%s'', {Encrypt N ''%s''}, ''odbc''', [Approle, Approlepassword]));

so I cannot exclude the possibility that the "execute" and the "format" commands might put temporary stuff on the heap as well.

 

 

[edit] the GitHub feature request you mentioned was mine...

Edited by A.M. Hoornweg

Share this post


Link to post

Just construct a full string preliminary

connStr := format('... password ...');

then execute

connection.execute(connStr)

and then clear it

ZeroMemory(connStr, Length(connStr)*SizeOf(Char))

 

if DB access components are not doing something hidden, the only copy of connection string will now be erased.

Of course, you'll have to erase contents of Windows edit control as well. That's probably a harder task 🙂 Maybe overwriting .Text property with some random string will help.

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×