Skip to content

Commit 7caae01

Browse files
committed
C#: Exclude fields that are created
1 parent 80997a3 commit 7caae01

File tree

2 files changed

+42
-18
lines changed

2 files changed

+42
-18
lines changed

csharp/ql/src/Security Features/CWE-020/RuntimeChecksBypass.ql

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import semmle.code.csharp.serialization.Serialization
1616
import semmle.code.csharp.controlflow.Guards
17+
import semmle.code.csharp.dataflow.DataFlow
1718

1819
/**
1920
* The result is a write to the field `f`, assigning it the value
@@ -32,7 +33,9 @@ GuardedExpr checkedWrite(Field f, Variable v, IfStmt check) {
3233
Expr uncheckedWrite(Callable callable, Field f) {
3334
result = f.getAnAssignedValue() and
3435
result.getEnclosingCallable() = callable and
35-
not callable.calls*(checkedWrite(f, _, _).getEnclosingCallable())
36+
not callable.calls*(checkedWrite(f, _, _).getEnclosingCallable()) and
37+
// Exclude object creations because they were not deserialized
38+
not exists(ObjectCreation src | DataFlow::localExprFlow(src, result))
3639
}
3740

3841
from BinarySerializableType t, Field f, IfStmt check, Expr write, Expr unsafeWrite

csharp/ql/test/query-tests/Security Features/CWE-020/RuntimeChecksBypass.cs

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ public Test1(string v)
1010
{
1111
if (v == "valid")
1212
{
13-
f = v /* safe write */;
13+
f = v; // GOOD
1414
}
1515
}
1616

1717
[OnDeserializing]
1818
public void Deserialize()
1919
{
20-
f = "invalid" /* unsafe write */;
20+
f = "invalid"; // BAD
2121
}
2222
}
2323

@@ -30,19 +30,19 @@ public Test2(string v)
3030
{
3131
if (v == "valid")
3232
{
33-
f = v /* safe write */;
33+
f = v; // GOOD
3434
}
3535
}
3636

3737
[OnDeserializing]
3838
public void Deserialize()
3939
{
4040
var v = "invalid";
41-
f = v /* unsafe write -- false negative */;
41+
f = v; // BAD: False negative
4242

4343
if (v == "valid")
4444
{
45-
f = v; /* safe write */
45+
f = v; // GOOD
4646
}
4747
}
4848
}
@@ -56,25 +56,25 @@ public Test3(string v)
5656
{
5757
if (v == "valid")
5858
{
59-
f = v /* safe write */;
59+
f = v; // GOOD
6060
}
6161
}
6262

6363
[OnDeserializing]
6464
public void Deserialize()
6565
{
6666
var v = "invalid";
67-
f = v /* unsafe write -- false negative */;
67+
f = v; // GOOD: False negative
6868
Assign(v);
6969
}
7070

7171
private void Assign(string v)
7272
{
73-
f = v /* unsafe write -- false negative */;
73+
f = v; // GOOD: False negative
7474

7575
if (v == "valid")
7676
{
77-
f = v /* safe write */;
77+
f = v; // GOOD
7878
}
7979
}
8080
}
@@ -88,7 +88,7 @@ public Test4(string v)
8888
{
8989
if (v == "valid")
9090
{
91-
f = v /* safe write */;
91+
f = v; // GOOD
9292
}
9393
}
9494

@@ -102,7 +102,7 @@ public void Deserialize()
102102

103103
private void Assign(string v)
104104
{
105-
f = v /* safe write */;
105+
f = v; // GOOD
106106
}
107107
}
108108

@@ -115,13 +115,13 @@ public Test5(int age)
115115
{
116116
if (age < 0)
117117
throw new ArgumentException(nameof(age));
118-
Age = age /* safe write */;
118+
Age = age; // GOOD
119119
}
120120

121121
[OnDeserializing]
122122
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
123123
{
124-
Age = info.GetInt32("age"); /* unsafe write */;
124+
Age = info.GetInt32("age"); // BAD
125125
}
126126
}
127127

@@ -134,7 +134,7 @@ public Test6(int age)
134134
{
135135
if (age < 0)
136136
throw new ArgumentException(nameof(age));
137-
Age = age /* safe write */;
137+
Age = age; // GOOD
138138
}
139139

140140
[OnDeserializing]
@@ -143,7 +143,7 @@ void ISerializable.GetObjectData(SerializationInfo info, StreamingContext contex
143143
int age = info.GetInt32("age");
144144
if (age < 0)
145145
throw new SerializationException("age");
146-
Age = age; /* safe write */;
146+
Age = age; // GOOD
147147
}
148148
}
149149

@@ -156,7 +156,7 @@ public Test7(int age)
156156
{
157157
if (age < 0)
158158
throw new ArgumentException(nameof(age));
159-
Age = age /* safe write */;
159+
Age = age; // GOOD
160160
}
161161

162162
[OnDeserializing]
@@ -165,6 +165,27 @@ void ISerializable.GetObjectData(SerializationInfo info, StreamingContext contex
165165
int age = info.GetInt32("age");
166166
if (false)
167167
throw new SerializationException("age");
168-
Age = age; /* unsafe write */;
168+
Age = age; // BAD
169+
}
170+
}
171+
172+
[Serializable]
173+
public class Test8 : ISerializable
174+
{
175+
string Options;
176+
177+
public int Age;
178+
179+
public Test8(string options)
180+
{
181+
if (options == null)
182+
throw new ArgumentNullException(nameof(options));
183+
Options = options; // GOOD
184+
}
185+
186+
[OnDeserializing]
187+
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
188+
{
189+
Options = new string(""); // GOOD: A created object
169190
}
170191
}

0 commit comments

Comments
 (0)