"using" and security

As I’m looking throughout posts on the Internet for solutions to my problems. I find that people often use using as a built-in function rather than at the top of their file. Same posts, of which I guess was about 5 mention different security reasons of using it. Once, alleged problem was “resource leak”, which I have assume is something of a negative Heartbleed or buffer underload.

Whilst I would put using MyNamespaceHere; on top of the file, they would put in a function fashion as such:

using (var variable = MyNameSpace.MyClass.MyFuncion()) {
}
  • For one, does Unity have my back on this one, after all I don’t code for raw .NET interface but for Unity’s C++ written interface so any fallacies are technically absorbed by Unity’s code, right?
  • For second, does it really matter if there’s a resource leak when there’s tons of decompilers for Unity games? Hacker could simply decompile my game, put his own code in there and read all of these data anyway.

Other than different places of accessibility, does it matter?

One could complain about memory overuse, but if my function is returning random numbers (on purpose), and I ask 10 million random numbers, and return them, it’s not going to keep that 10 million numbers in its memory, it cleans them up right? “Garbage collection” and what not? The only ones that stay are the ones that I decided to assign somewhere. On function’s end it drops it’s internal processing data, right? And if not, why doesn’t it do it automatically? Why on Earth would you want that data stay there?

Once again, I’m ignorant on the topic, so have patience.

In C# “using” has a couple of different meanings.

When you write “using UnityEngine;” at the top of your file, that is the using directive.
When you write “using (var variable = something)” inside a function, that is the using statement. Same word, but completely different meaning.

The using statement is a syntax for saying “automatically dispose of this once I’m done with it”. This is especially convenient because it ensures the object gets disposed even if an exception gets thrown, kind of like a try…finally block.

C# has automatic memory management, so most objects don’t need to be “disposed of”; the garbage collector just cleans them up whenever they’re no longer being used. So the using statement is only used on special objects–specifically, ones that implement the IDisposable interface. These are objects that have some special reason that they need to do clean-up separate from simply freeing memory; for example, if they’re using some hardware resource and you need them to stop using it so that someone else can use it.

If you forget to dispose of it, an IDisposable object probably would be smart enough to do that clean-up automatically when it gets garbage collected (not strictly required, but usually a good idea for whoever’s writing that class). However, that might not be for a long time! Objects aren’t guaranteed to get garbage-collected immediately when you stop using them–the only guarantee is that they’ll be collected no later than when your program quits.

The garbage collector isn’t trying to grab memory as fast as possible, it’s trying to avoid slowing your program down, and a lot of the time that means waiting before it collects stuff. It will get more aggressive if it sees that you’re low on memory, but it has no way of knowing if there’s some other reason that an object needs to get cleaned up quickly.

If an object implements the IDisposable interface, it’s usually a good idea to dispose of it promptly when you no longer need it. (But for some reason other than memory usage, so the garbage collector can’t detect it automatically.)

If you don’t dispose of it, that could be a security issue, but more commonly it’s a performance issue. Depends on the object in question (and possibly on how you’re using it).

1 Like

Can you post a link to one of these? I’d like to see the original context of that because I’m not really sure what you are talking about in most of this post.

For one thing, a C# “using” directive that goes at the top of the file, such as “using System.Collections” or whatever is something completely different and unrelated to a “using” block in C#. They use the same key word but they are completely different things, so it’s not really a matter of choosing one or the other.

Another thing: as I understand, the “using” block that you are describing is for ensuring that “unmanaged” objects are garbage collected (someone correct me if I’m wrong). Are you actually use “unmanaged” objects? It’s very unlikely that you are unless you are linking-in a native compiled assembly, like a dll that was written in C++ or something. Unless you know for certain that you are using unmanaged objects in memory, I doubt if this security concern applies, nor would you actually need these “using” blocks for anything,

I’ve seen some of them over several months, I never really saved them, but the last one I dug up here:
https://stackoverflow.com/a/39131803

The guy in that particular post is doing cryptography (note the use of namespace
System.Security.Cryptography). Cryptography generally revolves around secret numbers that allow you and your friends to understand the codes that look like gibberish to people who don’t know those secret numbers. You want to make it as hard as possible for an enemy to learn them, and one of the standard precautions is to erase them from memory as soon as you’re done using them.

(Note that “erasing from memory” is not the same as garbage collection–garbage collection marks the memory as able to be used again, but doesn’t actually erase the values that were written there until the space is needed for something else.)

Now, the secret numbers still existed in memory for some window of time, so it’s still possible for someone to snoop them. But security is all about making things as hard for the attacker as possible, so you want that window of opportunity to be as small as you can make it.

Still, does it matter for me really?:

Who would care to hack an offline game and read those variables? How evil can reading your own hashes be?

Yes, if you are doing cryptography, then it matters for you.

Have you ever tried decompiling a game? Finding the one number you’re looking for isn’t trivial. Decompiling isn’t necessarily easier than snooping on memory.

Also, there are attack scenarios where the attacker might be able to snoop on memory but not be able to modify the program being run (maybe it’s a multi-user system, or maybe the attacker only gains access to the system after the program finishes running). In those cases, it doesn’t matter how easy the program is to decompile.

Cryptography is subtle. If you are not an expert, you would be well-advised to follow common best practices even if you’re not sure whether they matter for you.

Addendum: Not all hashing is for security purposes. If you are using hash functions for some purpose completely unrelated to security, then disposal probably doesn’t matter, but I’d have to read the details on the class in question to see if maybe they have some other non-security-related reason for implementing IDisposable.

In most cases, it is easier to properly dispose of an object than it is to research why the object is IDisposable in the first place and figure out whether it matters for you.

I’m not sure what your post is about. You seem unsure about the different uses of the ‘using’ clause, then ask if Unity has you back on this (‘this’ being something you seem unsure of), and then ask if it matters to you.

What is your question, exactly?

Do we need linguistic security features for the purpose of building games in Unity? If you do, you do. If you don’t know, don’t sweat it. But this is pretty much irrelevant, because you are discussing a feature of C#. I suggest you ask this question on an MS Forum (and I’m sure that there the answer will be swift and very, very explicit).

this is just short notation for

var variable = default(IDisposable);
try
{
  variable = MyNameSpace.MyClass.MyFunction();
  ...
}
finally
{
  variable?.Dispose();
}

it is here to ensure .Dispose will be called anyway, even in case of any exception thrown during that code execution. Nothing more. Works with any IDisposable implementation.