[Part 2] Is c# safe? Readonly fields... Really readonly?
Hi
Today I present you part 2 of "Is c# safe" series.
Few days ago I though about whether possibility to set value to readonly field outside the constructor.
Quoting the Microsoft website:
As last time, I wrote unit tests to see if it is possible.
commit to my github
Unfortunately Microsoft... Using reflection above sentence isn't true.
I added new class named "InternalCallReadonlyVsConst" and it looks like below
I wrote tests checking the possiblity to change value of readonly and static readonly fields.
Answer is yes, both of them you can change the value.
I was thinking about how to protect yourself, so I added const fields as below.
When I try change the value of const fields I got "FieldAccessException" as you can see in my code.
You can draw the conclusion. If security of your application important to you use const fields when it is possible.
In the next part I will show more examples of how to defend against reflection.
Today I present you part 2 of "Is c# safe" series.
Few days ago I though about whether possibility to set value to readonly field outside the constructor.
Quoting the Microsoft website:
"The readonly keyword is a modifier that you can use on fields. When a field declaration includes a readonly modifier, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.
Example
In this example, the value of the field year cannot be changed in the method ChangeYear, even though it is assigned a value in the class constructor..."
As last time, I wrote unit tests to see if it is possible.
commit to my github
Unfortunately Microsoft... Using reflection above sentence isn't true.
I added new class named "InternalCallReadonlyVsConst" and it looks like below
namespace InternalClasses
{
class InternalCallReadonlyVsConst
{
private readonly int privateReadonlyInt = 100;
private readonly string privateReadonlyString = "100";
private static readonly int privateStaticReadonlyInt = 100;
private static readonly string privateStaticReadonlyString = "100";
}
}
I wrote tests checking the possiblity to change value of readonly and static readonly fields.
Answer is yes, both of them you can change the value.
I was thinking about how to protect yourself, so I added const fields as below.
namespace InternalClasses
{
class InternalCallReadonlyVsConst
{
private readonly int privateReadonlyInt = 100;
private readonly string privateReadonlyString = "100";
private static readonly int privateStaticReadonlyInt = 100;
private static readonly string privateStaticReadonlyString = "100";
private const int privateConstInt = 100;
private const string privateConstString = "100";
}
}
When I try change the value of const fields I got "FieldAccessException" as you can see in my code.
[TestMethod()]
public void CreateInternalClassInstanceAndSetConstFields()
{
object InternalCallReadonlyVsConst = ReflectionHelper.CreateInstanceOfInternalClass(
"InternalClasses", "InternalClasses", "InternalCallReadonlyVsConst");
Assert.IsNotNull(InternalCallReadonlyVsConst);
object privateConstInt = ReflectionHelper.GetNonPublicIntFiledValue(InternalCallReadonlyVsConst,
"privateConstInt", InternalCallReadonlyVsConst.GetType());
Assert.IsNotNull(privateConstInt);
Assert.IsTrue(privateConstInt is Int32);
Assert.AreEqual(privateConstInt, 100);
Assert.ThrowsException< FieldAccessException>(()=> privateConstInt =
ReflectionHelper.GetAndSetValue(InternalCallReadonlyVsConst, 1234, "privateConstInt"));
Assert.IsNotNull(privateConstInt);
Assert.IsTrue(privateConstInt is Int32);
Assert.AreEqual(privateConstInt, 100);
object privateConstString = ReflectionHelper.GetNonPublicIntFiledValue(InternalCallReadonlyVsConst,
"privateConstString", InternalCallReadonlyVsConst.GetType());
Assert.IsNotNull(privateConstString);
Assert.IsTrue(privateConstString is string);
Assert.AreEqual(privateConstString, "100");
Assert.ThrowsException(() => privateConstString =
ReflectionHelper.GetAndSetValue(InternalCallReadonlyVsConst, "1234", "privateConstString"));
Assert.IsNotNull(privateConstString);
Assert.IsTrue(privateConstString is string);
Assert.AreEqual(privateConstString, "100");
}
You can draw the conclusion. If security of your application important to you use const fields when it is possible.
In the next part I will show more examples of how to defend against reflection.
Komentarze
Prześlij komentarz