Skip to content

Commit c530fbd

Browse files
committed
C# Threat Modeling Tests
1 parent 3c9c07e commit c530fbd

22 files changed

+460
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using System.Net.Sockets;
2+
using System.Data.SqlClient;
3+
4+
namespace My.Qltest
5+
{
6+
public class Test
7+
{
8+
private TestSources Sources = new TestSources();
9+
10+
//private ILogger Logger => throw null;
11+
private SqlConnection Connection => throw null;
12+
13+
private string BytesToString(byte[] bytes)
14+
{
15+
// Encode bytes to a UTF8 string.
16+
return System.Text.Encoding.UTF8.GetString(bytes);
17+
}
18+
19+
public void M1()
20+
{
21+
// Only a source if "remote" is a selected threat model.
22+
// This is included in the "default" threat model.
23+
using TcpClient client = new TcpClient("localhost", 1234);
24+
using NetworkStream stream = client.GetStream();
25+
byte[] buffer = new byte[1024];
26+
int bytesRead = stream.Read(buffer, 0, buffer.Length);
27+
28+
// SQL sink
29+
var command = new SqlCommand("SELECT * FROM Users WHERE Username = '" + BytesToString(buffer) + "'", Connection);
30+
}
31+
32+
public void M2()
33+
{
34+
// Only a source if "database" is a selected threat model.
35+
string result = Sources.ExecuteQuery("SELECT * FROM foo");
36+
37+
// SQL sink
38+
var command = new SqlCommand("SELECT * FROM Users WHERE Username = '" + result + "'", Connection);
39+
}
40+
41+
public void M3()
42+
{
43+
// Only a source if "environment" is a selected threat model.
44+
string result = Sources.ReadEnv("foo");
45+
46+
// SQL sink
47+
var command = new SqlCommand("SELECT * FROM Users WHERE Username = '" + result + "'", Connection);
48+
49+
}
50+
51+
public void M4()
52+
{
53+
// Only a source if "custom" is a selected threat model.
54+
string result = Sources.GetCustom("foo");
55+
56+
// SQL sink
57+
var command = new SqlCommand("SELECT * FROM Users WHERE Username = '" + result + "'", Connection);
58+
}
59+
60+
public void M5()
61+
{
62+
// Only a source if "commandargs" is a selected threat model.
63+
string result = Sources.GetCliArg(0);
64+
65+
// SQL sink
66+
var command = new SqlCommand("SELECT * FROM Users WHERE Username = '" + result + "'", Connection);
67+
}
68+
}
69+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
private import csharp
2+
private import semmle.code.csharp.dataflow.DataFlow
3+
private import semmle.code.csharp.dataflow.internal.ExternalFlow
4+
private import semmle.code.csharp.security.dataflow.flowsources.FlowSources
5+
6+
private module ThreatModelConfig implements DataFlow::ConfigSig {
7+
predicate isSource(DataFlow::Node source) { source instanceof ThreatModelFlowSource }
8+
9+
predicate isSink(DataFlow::Node sink) { sinkNode(sink, _) }
10+
}
11+
12+
module ThreatModel = TaintTracking::Global<ThreatModelConfig>;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
namespace My.Qltest
2+
{
3+
4+
public class TestSources
5+
{
6+
public string ExecuteQuery(string query)
7+
{
8+
return null;
9+
}
10+
11+
public string ReadEnv(string env)
12+
{
13+
return null;
14+
}
15+
16+
public string GetCustom(string s)
17+
{
18+
return null;
19+
}
20+
21+
public string GetCliArg(int i)
22+
{
23+
return null;
24+
}
25+
}
26+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
semmle-extractor-options: /nostdlib /noconfig
2+
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/System.Data.SqlClient/4.8.5/System.Data.SqlClient.csproj
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
edges
2+
| Test.cs:13:45:13:49 | bytes : Byte[] [element] : Object | Test.cs:16:56:16:60 | access to parameter bytes : Byte[] [element] : Object |
3+
| Test.cs:16:56:16:60 | access to parameter bytes : Byte[] [element] : Object | Test.cs:16:20:16:61 | call to method GetString : String |
4+
| Test.cs:24:42:24:59 | call to method GetStream : NetworkStream | Test.cs:26:29:26:34 | access to local variable stream : NetworkStream |
5+
| Test.cs:26:29:26:34 | access to local variable stream : NetworkStream | Test.cs:26:41:26:46 | [post] access to local variable buffer : Byte[] [element] : Object |
6+
| Test.cs:26:41:26:46 | [post] access to local variable buffer : Byte[] [element] : Object | Test.cs:29:99:29:104 | access to local variable buffer : Byte[] [element] : Object |
7+
| Test.cs:29:85:29:105 | call to method BytesToString : String | Test.cs:29:42:29:111 | ... + ... |
8+
| Test.cs:29:99:29:104 | access to local variable buffer : Byte[] [element] : Object | Test.cs:13:45:13:49 | bytes : Byte[] [element] : Object |
9+
| Test.cs:29:99:29:104 | access to local variable buffer : Byte[] [element] : Object | Test.cs:29:85:29:105 | call to method BytesToString : String |
10+
nodes
11+
| Test.cs:13:45:13:49 | bytes : Byte[] [element] : Object | semmle.label | bytes : Byte[] [element] : Object |
12+
| Test.cs:16:20:16:61 | call to method GetString : String | semmle.label | call to method GetString : String |
13+
| Test.cs:16:56:16:60 | access to parameter bytes : Byte[] [element] : Object | semmle.label | access to parameter bytes : Byte[] [element] : Object |
14+
| Test.cs:24:42:24:59 | call to method GetStream : NetworkStream | semmle.label | call to method GetStream : NetworkStream |
15+
| Test.cs:26:29:26:34 | access to local variable stream : NetworkStream | semmle.label | access to local variable stream : NetworkStream |
16+
| Test.cs:26:41:26:46 | [post] access to local variable buffer : Byte[] [element] : Object | semmle.label | [post] access to local variable buffer : Byte[] [element] : Object |
17+
| Test.cs:29:42:29:111 | ... + ... | semmle.label | ... + ... |
18+
| Test.cs:29:85:29:105 | call to method BytesToString : String | semmle.label | call to method BytesToString : String |
19+
| Test.cs:29:99:29:104 | access to local variable buffer : Byte[] [element] : Object | semmle.label | access to local variable buffer : Byte[] [element] : Object |
20+
subpaths
21+
| Test.cs:29:99:29:104 | access to local variable buffer : Byte[] [element] : Object | Test.cs:13:45:13:49 | bytes : Byte[] [element] : Object | Test.cs:16:20:16:61 | call to method GetString : String | Test.cs:29:85:29:105 | call to method BytesToString : String |
22+
#select
23+
| Test.cs:24:42:24:59 | call to method GetStream : NetworkStream | Test.cs:29:42:29:111 | ... + ... |
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
extensions:
2+
3+
- addsTo:
4+
pack: codeql/java-all
5+
extensible: supportedThreatModels
6+
data: []
7+
8+
- addsTo:
9+
pack: codeql/java-all
10+
extensible: sourceModel
11+
data:
12+
- ["My.Qltest", "TestSources", False, "ExecuteQuery", "(System.String)", "", "ReturnValue", "database", "manual"]
13+
- ["My.Qltest", "TestSources", False, "ReadEnv", "(System.String)", "", "ReturnValue", "environment", "manual"]
14+
- ["My.Qltest", "TestSources", False, "GetCustom", "(System.String)", "", "ReturnValue", "custom", "manual"]
15+
- ["My.Qltest", "TestSources", False, "GetCliArg", "(System.Int32)", "", "ReturnValue", "commandargs", "manual"]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* This is a dataflow test using the "default" threat model.
3+
*/
4+
5+
import Test
6+
import ThreatModel::PathGraph
7+
8+
from ThreatModel::PathNode source, ThreatModel::PathNode sink
9+
where ThreatModel::flowPath(source, sink)
10+
select source, sink
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
edges
2+
| Test.cs:13:45:13:49 | bytes : Byte[] [element] : Object | Test.cs:16:56:16:60 | access to parameter bytes : Byte[] [element] : Object |
3+
| Test.cs:16:56:16:60 | access to parameter bytes : Byte[] [element] : Object | Test.cs:16:20:16:61 | call to method GetString : String |
4+
| Test.cs:24:42:24:59 | call to method GetStream : NetworkStream | Test.cs:26:29:26:34 | access to local variable stream : NetworkStream |
5+
| Test.cs:26:29:26:34 | access to local variable stream : NetworkStream | Test.cs:26:41:26:46 | [post] access to local variable buffer : Byte[] [element] : Object |
6+
| Test.cs:26:41:26:46 | [post] access to local variable buffer : Byte[] [element] : Object | Test.cs:29:99:29:104 | access to local variable buffer : Byte[] [element] : Object |
7+
| Test.cs:29:85:29:105 | call to method BytesToString : String | Test.cs:29:42:29:111 | ... + ... |
8+
| Test.cs:29:99:29:104 | access to local variable buffer : Byte[] [element] : Object | Test.cs:13:45:13:49 | bytes : Byte[] [element] : Object |
9+
| Test.cs:29:99:29:104 | access to local variable buffer : Byte[] [element] : Object | Test.cs:29:85:29:105 | call to method BytesToString : String |
10+
| Test.cs:35:29:35:69 | call to method ExecuteQuery : String | Test.cs:38:42:38:96 | ... + ... |
11+
nodes
12+
| Test.cs:13:45:13:49 | bytes : Byte[] [element] : Object | semmle.label | bytes : Byte[] [element] : Object |
13+
| Test.cs:16:20:16:61 | call to method GetString : String | semmle.label | call to method GetString : String |
14+
| Test.cs:16:56:16:60 | access to parameter bytes : Byte[] [element] : Object | semmle.label | access to parameter bytes : Byte[] [element] : Object |
15+
| Test.cs:24:42:24:59 | call to method GetStream : NetworkStream | semmle.label | call to method GetStream : NetworkStream |
16+
| Test.cs:26:29:26:34 | access to local variable stream : NetworkStream | semmle.label | access to local variable stream : NetworkStream |
17+
| Test.cs:26:41:26:46 | [post] access to local variable buffer : Byte[] [element] : Object | semmle.label | [post] access to local variable buffer : Byte[] [element] : Object |
18+
| Test.cs:29:42:29:111 | ... + ... | semmle.label | ... + ... |
19+
| Test.cs:29:85:29:105 | call to method BytesToString : String | semmle.label | call to method BytesToString : String |
20+
| Test.cs:29:99:29:104 | access to local variable buffer : Byte[] [element] : Object | semmle.label | access to local variable buffer : Byte[] [element] : Object |
21+
| Test.cs:35:29:35:69 | call to method ExecuteQuery : String | semmle.label | call to method ExecuteQuery : String |
22+
| Test.cs:38:42:38:96 | ... + ... | semmle.label | ... + ... |
23+
subpaths
24+
| Test.cs:29:99:29:104 | access to local variable buffer : Byte[] [element] : Object | Test.cs:13:45:13:49 | bytes : Byte[] [element] : Object | Test.cs:16:20:16:61 | call to method GetString : String | Test.cs:29:85:29:105 | call to method BytesToString : String |
25+
#select
26+
| Test.cs:24:42:24:59 | call to method GetStream : NetworkStream | Test.cs:29:42:29:111 | ... + ... |
27+
| Test.cs:35:29:35:69 | call to method ExecuteQuery : String | Test.cs:38:42:38:96 | ... + ... |
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
extensions:
2+
3+
- addsTo:
4+
pack: codeql/threat-models
5+
extensible: threatModelConfiguration
6+
data:
7+
- ["database", true, 0]
8+
9+
- addsTo:
10+
pack: codeql/java-all
11+
extensible: sourceModel
12+
data:
13+
- ["My.Qltest", "TestSources", False, "ExecuteQuery", "(System.String)", "", "ReturnValue", "database", "manual"]
14+
- ["My.Qltest", "TestSources", False, "ReadEnv", "(System.String)", "", "ReturnValue", "environment", "manual"]
15+
- ["My.Qltest", "TestSources", False, "GetCustom", "(System.String)", "", "ReturnValue", "custom", "manual"]
16+
- ["My.Qltest", "TestSources", False, "GetCliArg", "(System.Int32)", "", "ReturnValue", "commandargs", "manual"]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* This is a dataflow test using the "default" threat model with the
3+
* addition of "database".
4+
*/
5+
6+
import Test
7+
import ThreatModel::PathGraph
8+
9+
from ThreatModel::PathNode source, ThreatModel::PathNode sink
10+
where ThreatModel::flowPath(source, sink)
11+
select source, sink

0 commit comments

Comments
 (0)