Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit 903cffe

Browse files
authored
Merge pull request #317 from gagliardetto/standard-lib-pt-18
Add taint-tracking for `reflect` package
2 parents e9bf331 + 095baeb commit 903cffe

File tree

3 files changed

+669
-0
lines changed

3 files changed

+669
-0
lines changed

ql/src/semmle/go/frameworks/Stdlib.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import semmle.go.frameworks.stdlib.CompressLzw
1414
import semmle.go.frameworks.stdlib.CompressZlib
1515
import semmle.go.frameworks.stdlib.Path
1616
import semmle.go.frameworks.stdlib.PathFilepath
17+
import semmle.go.frameworks.stdlib.Reflect
1718

1819
/** A `String()` method. */
1920
class StringMethod extends TaintTracking::FunctionModel, Method {
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `reflect` package.
3+
*/
4+
5+
import go
6+
7+
/** Provides models of commonly used functions in the `reflect` package. */
8+
module Reflect {
9+
private class FunctionModels extends TaintTracking::FunctionModel {
10+
FunctionInput inp;
11+
FunctionOutput outp;
12+
13+
FunctionModels() {
14+
// signature: func Append(s Value, x ...Value) Value
15+
hasQualifiedName("reflect", "Append") and
16+
(inp.isParameter(_) and outp.isResult())
17+
or
18+
// signature: func AppendSlice(s Value, t Value) Value
19+
hasQualifiedName("reflect", "AppendSlice") and
20+
(inp.isParameter(_) and outp.isResult())
21+
or
22+
// signature: func Copy(dst Value, src Value) int
23+
hasQualifiedName("reflect", "Copy") and
24+
(inp.isParameter(1) and outp.isParameter(0))
25+
or
26+
// signature: func Indirect(v Value) Value
27+
hasQualifiedName("reflect", "Indirect") and
28+
(inp.isParameter(0) and outp.isResult())
29+
or
30+
// signature: func ValueOf(i interface{}) Value
31+
hasQualifiedName("reflect", "ValueOf") and
32+
(inp.isParameter(0) and outp.isResult())
33+
}
34+
35+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
36+
input = inp and output = outp
37+
}
38+
}
39+
40+
private class MethodModels extends TaintTracking::FunctionModel, Method {
41+
FunctionInput inp;
42+
FunctionOutput outp;
43+
44+
MethodModels() {
45+
// signature: func (*MapIter).Key() Value
46+
this.hasQualifiedName("reflect", "MapIter", "Key") and
47+
(inp.isReceiver() and outp.isResult())
48+
or
49+
// signature: func (*MapIter).Value() Value
50+
this.hasQualifiedName("reflect", "MapIter", "Value") and
51+
(inp.isReceiver() and outp.isResult())
52+
or
53+
// signature: func (StructTag).Get(key string) string
54+
this.hasQualifiedName("reflect", "StructTag", "Get") and
55+
(inp.isReceiver() and outp.isResult())
56+
or
57+
// signature: func (StructTag).Lookup(key string) (value string, ok bool)
58+
this.hasQualifiedName("reflect", "StructTag", "Lookup") and
59+
(inp.isReceiver() and outp.isResult(0))
60+
or
61+
// signature: func (Value).Addr() Value
62+
this.hasQualifiedName("reflect", "Value", "Addr") and
63+
(inp.isReceiver() and outp.isResult())
64+
or
65+
// signature: func (Value).Bytes() []byte
66+
this.hasQualifiedName("reflect", "Value", "Bytes") and
67+
(inp.isReceiver() and outp.isResult())
68+
or
69+
// signature: func (Value).Convert(t Type) Value
70+
this.hasQualifiedName("reflect", "Value", "Convert") and
71+
(inp.isReceiver() and outp.isResult())
72+
or
73+
// signature: func (Value).Elem() Value
74+
this.hasQualifiedName("reflect", "Value", "Elem") and
75+
(inp.isReceiver() and outp.isResult())
76+
or
77+
// signature: func (Value).Field(i int) Value
78+
this.hasQualifiedName("reflect", "Value", "Field") and
79+
(inp.isReceiver() and outp.isResult())
80+
or
81+
// signature: func (Value).FieldByIndex(index []int) Value
82+
this.hasQualifiedName("reflect", "Value", "FieldByIndex") and
83+
(inp.isReceiver() and outp.isResult())
84+
or
85+
// signature: func (Value).FieldByName(name string) Value
86+
this.hasQualifiedName("reflect", "Value", "FieldByName") and
87+
(inp.isReceiver() and outp.isResult())
88+
or
89+
// signature: func (Value).FieldByNameFunc(match func(string) bool) Value
90+
this.hasQualifiedName("reflect", "Value", "FieldByNameFunc") and
91+
(inp.isReceiver() and outp.isResult())
92+
or
93+
// signature: func (Value).Index(i int) Value
94+
this.hasQualifiedName("reflect", "Value", "Index") and
95+
(inp.isReceiver() and outp.isResult())
96+
or
97+
// signature: func (Value).Interface() (i interface{})
98+
this.hasQualifiedName("reflect", "Value", "Interface") and
99+
(inp.isReceiver() and outp.isResult())
100+
or
101+
// signature: func (Value).InterfaceData() [2]uintptr
102+
this.hasQualifiedName("reflect", "Value", "InterfaceData") and
103+
(inp.isReceiver() and outp.isResult())
104+
or
105+
// signature: func (Value).MapIndex(key Value) Value
106+
this.hasQualifiedName("reflect", "Value", "MapIndex") and
107+
(inp.isReceiver() and outp.isResult())
108+
or
109+
// signature: func (Value).MapKeys() []Value
110+
this.hasQualifiedName("reflect", "Value", "MapKeys") and
111+
(inp.isReceiver() and outp.isResult())
112+
or
113+
// signature: func (Value).MapRange() *MapIter
114+
this.hasQualifiedName("reflect", "Value", "MapRange") and
115+
(inp.isReceiver() and outp.isResult())
116+
or
117+
// signature: func (Value).Method(i int) Value
118+
this.hasQualifiedName("reflect", "Value", "Method") and
119+
(inp.isReceiver() and outp.isResult())
120+
or
121+
// signature: func (Value).MethodByName(name string) Value
122+
this.hasQualifiedName("reflect", "Value", "MethodByName") and
123+
(inp.isReceiver() and outp.isResult())
124+
or
125+
// signature: func (Value).Pointer() uintptr
126+
this.hasQualifiedName("reflect", "Value", "Pointer") and
127+
(inp.isReceiver() and outp.isResult())
128+
or
129+
// signature: func (Value).Recv() (x Value, ok bool)
130+
this.hasQualifiedName("reflect", "Value", "Recv") and
131+
(inp.isReceiver() and outp.isResult(0))
132+
or
133+
// signature: func (Value).Send(x Value)
134+
this.hasQualifiedName("reflect", "Value", "Send") and
135+
(inp.isParameter(0) and outp.isReceiver())
136+
or
137+
// signature: func (Value).Set(x Value)
138+
this.hasQualifiedName("reflect", "Value", "Set") and
139+
(inp.isParameter(0) and outp.isReceiver())
140+
or
141+
// signature: func (Value).SetBytes(x []byte)
142+
this.hasQualifiedName("reflect", "Value", "SetBytes") and
143+
(inp.isParameter(0) and outp.isReceiver())
144+
or
145+
// signature: func (Value).SetMapIndex(key Value, elem Value)
146+
this.hasQualifiedName("reflect", "Value", "SetMapIndex") and
147+
(inp.isParameter(_) and outp.isReceiver())
148+
or
149+
// signature: func (Value).SetPointer(x unsafe.Pointer)
150+
this.hasQualifiedName("reflect", "Value", "SetPointer") and
151+
(inp.isParameter(0) and outp.isReceiver())
152+
or
153+
// signature: func (Value).SetString(x string)
154+
this.hasQualifiedName("reflect", "Value", "SetString") and
155+
(inp.isParameter(0) and outp.isReceiver())
156+
or
157+
// signature: func (Value).Slice(i int, j int) Value
158+
this.hasQualifiedName("reflect", "Value", "Slice") and
159+
(inp.isReceiver() and outp.isResult())
160+
or
161+
// signature: func (Value).Slice3(i int, j int, k int) Value
162+
this.hasQualifiedName("reflect", "Value", "Slice3") and
163+
(inp.isReceiver() and outp.isResult())
164+
or
165+
// signature: func (Value).String() string
166+
this.hasQualifiedName("reflect", "Value", "String") and
167+
(inp.isReceiver() and outp.isResult())
168+
or
169+
// signature: func (Value).TryRecv() (x Value, ok bool)
170+
this.hasQualifiedName("reflect", "Value", "TryRecv") and
171+
(inp.isReceiver() and outp.isResult(0))
172+
or
173+
// signature: func (Value).TrySend(x Value) bool
174+
this.hasQualifiedName("reflect", "Value", "TrySend") and
175+
(inp.isParameter(0) and outp.isReceiver())
176+
or
177+
// signature: func (Value).UnsafeAddr() uintptr
178+
this.hasQualifiedName("reflect", "Value", "UnsafeAddr") and
179+
(inp.isReceiver() and outp.isResult())
180+
}
181+
182+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
183+
input = inp and output = outp
184+
}
185+
}
186+
}

0 commit comments

Comments
 (0)