4

I have created a variable in C#. Now I want to clear the variables value from the computer memory. Is there any way to do that?

Below is my current attempt at deleting the value of recordLine, but I can still read the value from memory with DumpIt even though I set the variable to null and call garbage collection.

private void Extract_SLST_VariableLine()
{
      StreamReader file = new StreamReader(FilePath + FileName);
      while (!file.EndOfStream)
      {

            string recordLine = null;
            if ((recordLine = file.ReadLine()).Trim() != string.Empty)
            {
                  console.writeline(recordLine);
            }
            recordLine=null;
            gc.collect();

      }
}
4
  • 2
    You can reboot...
    – ThoriumBR
    Commented Jul 4, 2019 at 10:30
  • I don't know Garbage collector working or not but the values are retrievabale while using dumpit.exe Commented Jul 4, 2019 at 11:23
  • Similar question for Java: security.stackexchange.com/questions/148282/…
    – Anders
    Commented Jul 4, 2019 at 11:25
  • @ThoriumBR Rebooting only works if the page containing the data wasn't written to swap space, or it was and has subsequently been overwritten and the overwrite actually caused the data on the media to be overwritten (SSD wear levelling, I'm looking at you).
    – user
    Commented Jul 4, 2019 at 13:31

4 Answers 4

4

Just setting a string to null or calling the GC will not help here. It might delete the reference to the value, but not the value itself. After GC, it may be overwritten, but there is no guarantee that it will happend anytime soon.

What you need instead is something aking to a SecureString, that implements a Dispose method and some obfuscation. However, the security it provides is limited:

We don't recommend that you use the SecureString class for new development. For more information, see SecureString shouldn't be used on GitHub.

SecureString is a string type that provides a measure of security. It tries to avoid storing potentially sensitive strings in process memory as plain text. (For limitations, however, see the How secure is SecureString? section.)

The problem here is that if there is sufficently advanced malware with sufficiently high priviliges on your system, no secrets are safe no matter what fancy C# types you wrap them in. So I am not sure this is a problem with a solution.

If you do use a secure string, think about how you get the value into and out of it. If it passes through an ordinary string, you have gained absolutely nothing.

2
  • The class documentation you linked to includes a warning: "We don't recommend that you use the SecureString class for new development. For more information, see SecureString shouldn't be used on GitHub."
    – Philipp
    Commented Jul 4, 2019 at 11:52
  • 1
    @Philipp Ah, thanks. Long time since I worked with C#, apparently technology evolves. See my edit. Thanks again.
    – Anders
    Commented Jul 4, 2019 at 12:05
0

To a first approximation, you can't. There's technically ways - things like SecureString (deprecated) or P/Invoking SecureZeroMemeory - but the problem you're trying to solve is hard to solve in user-space programs at all, and much harder still in memory-managed runtimes like .NET (or JVM/CPython/Ruby/Node/PHP/etc.). Garbage collection can copy values around such that their current location when you delete them isn't the only place the value exists. Memory can be paged out to persistent storage and not erased from there. For that matter, a malicious process could read the data out of the program's address space before it's erased...

What, you think the last is implausible? Then why are you worrying about this at all? Without high privileges, a process running under user A can no more read dump files from a user B process than it can read the user B process' address space directly. Besides, you can turn off dumpfile generation. With high enough privileges, you can read the address space of any other process directly, in real-time (or close enough) - this is how debuggers work - and copy any data you want to anywhere you want (and also control the program flow to do whatever you want it to do, with secrets or otherwise).

In other words, if your threat model doesn't include "malware running either as the current user or as a highly-privileged user", you don't have to worry (at least so long as you aren't creating memory dumps and leaving them in insecure locations, including on any unencrypted drive that an attacker might have physical access to). If your threat model does include such attackers... you've already lost, pretty much. There is extremely little that can be done in the face of such things, and what there is, mostly involves moving code execution off the main processor and out of OS-readable memory entirely.

2
  • Citation needed for "a process running under user A can no more read dump files from a user B process than it can read the user B process' address space directly". Consider that this is exactly how a Microsoft Azure signing key was disclosed.
    – Ben Voigt
    Commented Sep 22, 2023 at 20:20
  • I mean, sure, if you move the dump file to an unsecured location, it can be read. But by default they are created in a secure location, and moving anything sensitive to an insecure location is a far more obvious, and easily-prevented, failure than generating crash dumps but ensuring they never contain sensitive data!
    – CBHacking
    Commented Sep 23, 2023 at 3:52
-2

As the variables store the memory on the heap If we assign variable to null it will just change the pointer and access the null reference with out deleting the previous variable it applies to even reassigning the variable also. Using IDisposable interface in C# we can remove the variables details from the memory by calling the garbage collector manually.

The below code will call the Dispose function and collects the all variables from the class and remove.

Public class Process : IDisposable {

private void Extract_SLST_VariableLine()
{
    try
    {
        StreamReader file = new StreamReader(FilePath + FileName);
        while (!file.EndOfStream)
        {

            string recordLine = null;
            if ((recordLine = file.ReadLine()).Trim() != string.Empty)
            {
                console.writeline(recordLine);
            }
            recordLine=null;
        }
    }
    catch()
    {
    }
    finally
    {
        Dispose();
    }
}

}

 public void Dispose()
 {

        GC.Collect();
        GC.SuppressFinalize(this);
 }

For more reference you can find in the follwoing links.. https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose

4
  • 1
    The GC collection doesn't delete the value, it just tells the OS to reuse that area of memory. The value is still there in memory, your code just no longer has any direct handle to it.
    – anon
    Commented Jul 11, 2019 at 15:51
  • @NicHartley any other way to delete the values from memory permanently ?
    – anvesh
    Commented Jul 15, 2019 at 18:00
  • 1
    Read the current top-voted answer on this question.
    – anon
    Commented Jul 15, 2019 at 18:01
  • @NicHartley I have a requirement where I get the credit card number with other details in a json from API call. so I have to store the details in variable. and then I have to read 7th digit of the card number. The top-voted answer doesn't suit to my requirement. Any other solution?
    – anvesh
    Commented Jul 15, 2019 at 19:16
-2

C# handles garbage collection automatically, you can call it explicitly with GC.Collect() however it is considered bad practice.

Below is a far more succinct and detailed explanation than I am equipped to give.

Alternatively why not just overwrite the variable with a dummy value? You could use null I guess but you would have to be careful of causing an exception and add in checks accordingly.

Then call GC.Collect() to clear the now unassigned data from memory. Whether that actually work or not I'm not sure.

EDIT: Based on comments below it does not.

See slightly ugly example...

var foo = 'sensitive';
// Your code
foo = null;
// call GC.Collect()

What's so wrong about using GC.Collect()?

GC.Collect() documentation

13
  • 2
    Setting the variable to null does not overwrite the memory. My guess is that you can't do that with a string (not sure, though). Also, the GC might release the memory so it may be overwritten later, but it does not overwrite it immediately.
    – Anders
    Commented Jul 4, 2019 at 11:21
  • 1
    @MechMK1 There is a exe called dumpit , it is used to collect memory dump and generate as txt format. when i search my variable value from it shows all Commented Jul 4, 2019 at 11:34
  • 2
    @RichC Setting to null does not overwrite. Calling GC makes no difference.
    – Anders
    Commented Jul 4, 2019 at 11:37
  • 1
    @RichC tq for ur support Commented Jul 4, 2019 at 11:51
  • 2
    Overwriting doesn't work in C# (e.g. foo = "sensitive"; foo = "masking###"; ) because of the way C# strings are immutable. When you try to modify a string, a new string is allocated. To have some measure of control about where strings are allocated, the P/Invoke and pointers will need to be used, but there will still be holes in this approach.
    – Ants
    Commented Jul 5, 2019 at 15:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .