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

Commit e7f2fb2

Browse files
committed
Add taint-tracking for reflect package
1 parent aac303c commit e7f2fb2

File tree

3 files changed

+856
-0
lines changed

3 files changed

+856
-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: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
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+
(
17+
inp.isParameter(_) and outp.isResult()
18+
or
19+
inp.isParameter(any(int i | i >= 1)) and outp.isParameter(0)
20+
)
21+
or
22+
// signature: func AppendSlice(s Value, t Value) Value
23+
hasQualifiedName("reflect", "AppendSlice") and
24+
(
25+
inp.isParameter(_) and outp.isResult()
26+
or
27+
inp.isParameter(1) and outp.isParameter(0)
28+
)
29+
or
30+
// signature: func Copy(dst Value, src Value) int
31+
hasQualifiedName("reflect", "Copy") and
32+
(inp.isParameter(1) and outp.isParameter(0))
33+
or
34+
// signature: func Indirect(v Value) Value
35+
hasQualifiedName("reflect", "Indirect") and
36+
(inp.isParameter(0) and outp.isResult())
37+
or
38+
// signature: func ValueOf(i interface{}) Value
39+
hasQualifiedName("reflect", "ValueOf") and
40+
(inp.isParameter(0) and outp.isResult())
41+
}
42+
43+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
44+
input = inp and output = outp
45+
}
46+
}
47+
48+
private class MethodModels extends TaintTracking::FunctionModel, Method {
49+
FunctionInput inp;
50+
FunctionOutput outp;
51+
52+
MethodModels() {
53+
// signature: func (*MapIter).Key() Value
54+
this.hasQualifiedName("reflect", "MapIter", "Key") and
55+
(inp.isReceiver() and outp.isResult())
56+
or
57+
// signature: func (*MapIter).Value() Value
58+
this.hasQualifiedName("reflect", "MapIter", "Value") and
59+
(inp.isReceiver() and outp.isResult())
60+
or
61+
// signature: func (StructTag).Get(key string) string
62+
this.hasQualifiedName("reflect", "StructTag", "Get") and
63+
(inp.isReceiver() and outp.isResult())
64+
or
65+
// signature: func (StructTag).Lookup(key string) (value string, ok bool)
66+
this.hasQualifiedName("reflect", "StructTag", "Lookup") and
67+
(inp.isReceiver() and outp.isResult(0))
68+
or
69+
// signature: func (Value).Addr() Value
70+
this.hasQualifiedName("reflect", "Value", "Addr") and
71+
(inp.isReceiver() and outp.isResult())
72+
or
73+
// signature: func (Value).Bool() bool
74+
this.hasQualifiedName("reflect", "Value", "Bool") and
75+
(inp.isReceiver() and outp.isResult())
76+
or
77+
// signature: func (Value).Bytes() []byte
78+
this.hasQualifiedName("reflect", "Value", "Bytes") and
79+
(inp.isReceiver() and outp.isResult())
80+
or
81+
// signature: func (Value).Complex() complex128
82+
this.hasQualifiedName("reflect", "Value", "Complex") and
83+
(inp.isReceiver() and outp.isResult())
84+
or
85+
// signature: func (Value).Convert(t Type) Value
86+
this.hasQualifiedName("reflect", "Value", "Convert") and
87+
(inp.isReceiver() and outp.isResult())
88+
or
89+
// signature: func (Value).Elem() Value
90+
this.hasQualifiedName("reflect", "Value", "Elem") and
91+
(inp.isReceiver() and outp.isResult())
92+
or
93+
// signature: func (Value).Field(i int) Value
94+
this.hasQualifiedName("reflect", "Value", "Field") and
95+
(inp.isReceiver() and outp.isResult())
96+
or
97+
// signature: func (Value).FieldByIndex(index []int) Value
98+
this.hasQualifiedName("reflect", "Value", "FieldByIndex") and
99+
(inp.isReceiver() and outp.isResult())
100+
or
101+
// signature: func (Value).FieldByName(name string) Value
102+
this.hasQualifiedName("reflect", "Value", "FieldByName") and
103+
(inp.isReceiver() and outp.isResult())
104+
or
105+
// signature: func (Value).FieldByNameFunc(match func(string) bool) Value
106+
this.hasQualifiedName("reflect", "Value", "FieldByNameFunc") and
107+
(inp.isReceiver() and outp.isResult())
108+
or
109+
// signature: func (Value).Float() float64
110+
this.hasQualifiedName("reflect", "Value", "Float") and
111+
(inp.isReceiver() and outp.isResult())
112+
or
113+
// signature: func (Value).Index(i int) Value
114+
this.hasQualifiedName("reflect", "Value", "Index") and
115+
(inp.isReceiver() and outp.isResult())
116+
or
117+
// signature: func (Value).Int() int64
118+
this.hasQualifiedName("reflect", "Value", "Int") and
119+
(inp.isReceiver() and outp.isResult())
120+
or
121+
// signature: func (Value).Interface() (i interface{})
122+
this.hasQualifiedName("reflect", "Value", "Interface") and
123+
(inp.isReceiver() and outp.isResult())
124+
or
125+
// signature: func (Value).InterfaceData() [2]uintptr
126+
this.hasQualifiedName("reflect", "Value", "InterfaceData") and
127+
(inp.isReceiver() and outp.isResult())
128+
or
129+
// signature: func (Value).MapIndex(key Value) Value
130+
this.hasQualifiedName("reflect", "Value", "MapIndex") and
131+
(inp.isReceiver() and outp.isResult())
132+
or
133+
// signature: func (Value).MapKeys() []Value
134+
this.hasQualifiedName("reflect", "Value", "MapKeys") and
135+
(inp.isReceiver() and outp.isResult())
136+
or
137+
// signature: func (Value).MapRange() *MapIter
138+
this.hasQualifiedName("reflect", "Value", "MapRange") and
139+
(inp.isReceiver() and outp.isResult())
140+
or
141+
// signature: func (Value).Method(i int) Value
142+
this.hasQualifiedName("reflect", "Value", "Method") and
143+
(inp.isReceiver() and outp.isResult())
144+
or
145+
// signature: func (Value).MethodByName(name string) Value
146+
this.hasQualifiedName("reflect", "Value", "MethodByName") and
147+
(inp.isReceiver() and outp.isResult())
148+
or
149+
// signature: func (Value).Pointer() uintptr
150+
this.hasQualifiedName("reflect", "Value", "Pointer") and
151+
(inp.isReceiver() and outp.isResult())
152+
or
153+
// signature: func (Value).Recv() (x Value, ok bool)
154+
this.hasQualifiedName("reflect", "Value", "Recv") and
155+
(inp.isReceiver() and outp.isResult(0))
156+
or
157+
// signature: func (Value).Send(x Value)
158+
this.hasQualifiedName("reflect", "Value", "Send") and
159+
(inp.isParameter(0) and outp.isReceiver())
160+
or
161+
// signature: func (Value).Set(x Value)
162+
this.hasQualifiedName("reflect", "Value", "Set") and
163+
(inp.isParameter(0) and outp.isReceiver())
164+
or
165+
// signature: func (Value).SetBool(x bool)
166+
this.hasQualifiedName("reflect", "Value", "SetBool") and
167+
(inp.isParameter(0) and outp.isReceiver())
168+
or
169+
// signature: func (Value).SetBytes(x []byte)
170+
this.hasQualifiedName("reflect", "Value", "SetBytes") and
171+
(inp.isParameter(0) and outp.isReceiver())
172+
or
173+
// signature: func (Value).SetComplex(x complex128)
174+
this.hasQualifiedName("reflect", "Value", "SetComplex") and
175+
(inp.isParameter(0) and outp.isReceiver())
176+
or
177+
// signature: func (Value).SetFloat(x float64)
178+
this.hasQualifiedName("reflect", "Value", "SetFloat") and
179+
(inp.isParameter(0) and outp.isReceiver())
180+
or
181+
// signature: func (Value).SetInt(x int64)
182+
this.hasQualifiedName("reflect", "Value", "SetInt") and
183+
(inp.isParameter(0) and outp.isReceiver())
184+
or
185+
// signature: func (Value).SetMapIndex(key Value, elem Value)
186+
this.hasQualifiedName("reflect", "Value", "SetMapIndex") and
187+
(inp.isParameter(_) and outp.isReceiver())
188+
or
189+
// signature: func (Value).SetPointer(x unsafe.Pointer)
190+
this.hasQualifiedName("reflect", "Value", "SetPointer") and
191+
(inp.isParameter(0) and outp.isReceiver())
192+
or
193+
// signature: func (Value).SetString(x string)
194+
this.hasQualifiedName("reflect", "Value", "SetString") and
195+
(inp.isParameter(0) and outp.isReceiver())
196+
or
197+
// signature: func (Value).SetUint(x uint64)
198+
this.hasQualifiedName("reflect", "Value", "SetUint") and
199+
(inp.isParameter(0) and outp.isReceiver())
200+
or
201+
// signature: func (Value).Slice(i int, j int) Value
202+
this.hasQualifiedName("reflect", "Value", "Slice") and
203+
(inp.isReceiver() and outp.isResult())
204+
or
205+
// signature: func (Value).Slice3(i int, j int, k int) Value
206+
this.hasQualifiedName("reflect", "Value", "Slice3") and
207+
(inp.isReceiver() and outp.isResult())
208+
or
209+
// signature: func (Value).String() string
210+
this.hasQualifiedName("reflect", "Value", "String") and
211+
(inp.isReceiver() and outp.isResult())
212+
or
213+
// signature: func (Value).TryRecv() (x Value, ok bool)
214+
this.hasQualifiedName("reflect", "Value", "TryRecv") and
215+
(inp.isReceiver() and outp.isResult(0))
216+
or
217+
// signature: func (Value).TrySend(x Value) bool
218+
this.hasQualifiedName("reflect", "Value", "TrySend") and
219+
(inp.isParameter(0) and outp.isReceiver())
220+
or
221+
// signature: func (Value).Uint() uint64
222+
this.hasQualifiedName("reflect", "Value", "Uint") and
223+
(inp.isReceiver() and outp.isResult())
224+
or
225+
// signature: func (Value).UnsafeAddr() uintptr
226+
this.hasQualifiedName("reflect", "Value", "UnsafeAddr") and
227+
(inp.isReceiver() and outp.isResult())
228+
}
229+
230+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
231+
input = inp and output = outp
232+
}
233+
}
234+
}

0 commit comments

Comments
 (0)