Skip to content

Commit 53dd269

Browse files
committed
Go: Threat model tests
1 parent 7f19f44 commit 53dd269

23 files changed

+362
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
private import go
2+
private import semmle.go.security.FlowSources
3+
private import semmle.go.dataflow.ExternalFlow
4+
private import semmle.go.dataflow.DataFlow
5+
6+
private module ThreatModelConfig implements DataFlow::ConfigSig {
7+
predicate isSource(DataFlow::Node source) { source instanceof ThreatModelFlowSource }
8+
9+
predicate isSink(DataFlow::Node sink) {
10+
sink = any(DataFlow::CallNode c | c.getTarget().getName() = "sink").getAnArgument()
11+
}
12+
}
13+
14+
module ThreatModelFlow = TaintTracking::Global<ThreatModelConfig>;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module semmle.go.dataflow.ThreatModels
2+
3+
go 1.22.3
4+
5+
require github.com/nonexistent/sources v0.0.0-20240601000000-0000000000000
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package main
2+
3+
import (
4+
"github.com/nonexistent/sources"
5+
"net/http"
6+
)
7+
8+
func Environment() {
9+
home := sources.ReadEnvironment("HOME")
10+
11+
sink("SELECT * FROM " + home)
12+
}
13+
14+
func Cli() {
15+
arg := sources.GetCliArg("arg")
16+
17+
sink("SELECT * FROM " + arg)
18+
}
19+
20+
func Custom() {
21+
query := sources.GetCustom("query")
22+
23+
sink("SELECT * FROM " + query)
24+
}
25+
26+
func StoredSqlInjection() {
27+
query := sources.ExecuteQuery("SELECT * FROM queries LIMIT 1")
28+
sink(query)
29+
}
30+
31+
func Handler(w http.ResponseWriter, r *http.Request) {
32+
query := r.URL.Query().Get("query")
33+
34+
sink("SELECT * FROM " + query)
35+
}
36+
37+
func sink(s string) {
38+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
edges
2+
| test.go:32:11:32:15 | selection of URL | test.go:32:11:32:23 | call to Query | provenance | MaD:735 |
3+
| test.go:32:11:32:23 | call to Query | test.go:32:11:32:36 | call to Get | provenance | MaD:742 |
4+
| test.go:32:11:32:36 | call to Get | test.go:34:7:34:30 | ...+... | provenance | |
5+
nodes
6+
| test.go:32:11:32:15 | selection of URL | semmle.label | selection of URL |
7+
| test.go:32:11:32:23 | call to Query | semmle.label | call to Query |
8+
| test.go:32:11:32:36 | call to Get | semmle.label | call to Get |
9+
| test.go:34:7:34:30 | ...+... | semmle.label | ...+... |
10+
subpaths
11+
#select
12+
| test.go:32:11:32:15 | selection of URL | test.go:34:7:34:30 | ...+... |
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/threat-models
5+
extensible: threatModelConfiguration
6+
data: []
7+
8+
- addsTo:
9+
pack: codeql/go-all
10+
extensible: sourceModel
11+
data:
12+
- ["github.com/nonexistent/sources", "", False, "ExecuteQuery", "", "", "ReturnValue", "database", "manual"]
13+
- ["github.com/nonexistent/sources", "", False, "ReadEnvironment", "", "", "ReturnValue", "environment", "manual"]
14+
- ["github.com/nonexistent/sources", "", False, "GetCustom", "", "", "ReturnValue", "custom", "manual"]
15+
- ["github.com/nonexistent/sources", "", False, "GetCliArg", "", "", "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 ThreatModelFlow::PathGraph
7+
8+
from ThreatModelFlow::PathNode source, ThreatModelFlow::PathNode sink
9+
where ThreatModelFlow::flowPath(source, sink)
10+
select source, sink
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
edges
2+
| test.go:27:11:27:63 | call to ExecuteQuery | test.go:28:7:28:11 | query | provenance | Src:MaD:1 |
3+
| test.go:32:11:32:15 | selection of URL | test.go:32:11:32:23 | call to Query | provenance | MaD:735 |
4+
| test.go:32:11:32:23 | call to Query | test.go:32:11:32:36 | call to Get | provenance | MaD:742 |
5+
| test.go:32:11:32:36 | call to Get | test.go:34:7:34:30 | ...+... | provenance | |
6+
nodes
7+
| test.go:27:11:27:63 | call to ExecuteQuery | semmle.label | call to ExecuteQuery |
8+
| test.go:28:7:28:11 | query | semmle.label | query |
9+
| test.go:32:11:32:15 | selection of URL | semmle.label | selection of URL |
10+
| test.go:32:11:32:23 | call to Query | semmle.label | call to Query |
11+
| test.go:32:11:32:36 | call to Get | semmle.label | call to Get |
12+
| test.go:34:7:34:30 | ...+... | semmle.label | ...+... |
13+
subpaths
14+
#select
15+
| test.go:27:11:27:63 | call to ExecuteQuery | test.go:28:7:28:11 | query |
16+
| test.go:32:11:32:15 | selection of URL | test.go:34:7:34:30 | ...+... |
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/go-all
11+
extensible: sourceModel
12+
data:
13+
- ["github.com/nonexistent/sources", "", False, "ExecuteQuery", "", "", "ReturnValue", "database", "manual"]
14+
- ["github.com/nonexistent/sources", "", False, "ReadEnvironment", "", "", "ReturnValue", "environment", "manual"]
15+
- ["github.com/nonexistent/sources", "", False, "GetCustom", "", "", "ReturnValue", "custom", "manual"]
16+
- ["github.com/nonexistent/sources", "", False, "GetCliArg", "", "", "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 ThreatModelFlow::PathGraph
8+
9+
from ThreatModelFlow::PathNode source, ThreatModelFlow::PathNode sink
10+
where ThreatModelFlow::flowPath(source, sink)
11+
select source, sink
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
edges
2+
| test.go:9:10:9:40 | call to ReadEnvironment | test.go:11:7:11:29 | ...+... | provenance | Src:MaD:2 |
3+
| test.go:15:9:15:32 | call to GetCliArg | test.go:17:7:17:28 | ...+... | provenance | Src:MaD:4 |
4+
| test.go:27:11:27:63 | call to ExecuteQuery | test.go:28:7:28:11 | query | provenance | Src:MaD:1 |
5+
| test.go:32:11:32:15 | selection of URL | test.go:32:11:32:23 | call to Query | provenance | MaD:735 |
6+
| test.go:32:11:32:23 | call to Query | test.go:32:11:32:36 | call to Get | provenance | MaD:742 |
7+
| test.go:32:11:32:36 | call to Get | test.go:34:7:34:30 | ...+... | provenance | |
8+
nodes
9+
| test.go:9:10:9:40 | call to ReadEnvironment | semmle.label | call to ReadEnvironment |
10+
| test.go:11:7:11:29 | ...+... | semmle.label | ...+... |
11+
| test.go:15:9:15:32 | call to GetCliArg | semmle.label | call to GetCliArg |
12+
| test.go:17:7:17:28 | ...+... | semmle.label | ...+... |
13+
| test.go:27:11:27:63 | call to ExecuteQuery | semmle.label | call to ExecuteQuery |
14+
| test.go:28:7:28:11 | query | semmle.label | query |
15+
| test.go:32:11:32:15 | selection of URL | semmle.label | selection of URL |
16+
| test.go:32:11:32:23 | call to Query | semmle.label | call to Query |
17+
| test.go:32:11:32:36 | call to Get | semmle.label | call to Get |
18+
| test.go:34:7:34:30 | ...+... | semmle.label | ...+... |
19+
subpaths
20+
#select
21+
| test.go:9:10:9:40 | call to ReadEnvironment | test.go:11:7:11:29 | ...+... |
22+
| test.go:15:9:15:32 | call to GetCliArg | test.go:17:7:17:28 | ...+... |
23+
| test.go:27:11:27:63 | call to ExecuteQuery | test.go:28:7:28:11 | query |
24+
| test.go:32:11:32:15 | selection of URL | test.go:34:7:34:30 | ...+... |

0 commit comments

Comments
 (0)