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

Commit 455cf0c

Browse files
committed
Add support and tests for protobuf messages with map fields
1 parent b2d4e26 commit 455cf0c

File tree

6 files changed

+138
-25
lines changed

6 files changed

+138
-25
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@ module Protobuf {
153153
exists(DataFlow::ReadNode base | succ = DataFlow::getUnderlyingNode(base) |
154154
any(DataFlow::Write w).writesField(base, getAMessageField(), pred)
155155
)
156+
or
157+
exists(DataFlow::ReadNode base | succ = DataFlow::getUnderlyingNode(base) |
158+
any(DataFlow::Write w).writesElement(base, _, pred) and
159+
[succ.getType(), succ.getType().getPointerType()] instanceof MessageType
160+
)
156161
}
157162
}
158163
}

ql/test/library-tests/semmle/go/frameworks/Protobuf/TaintFlows.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
| testDeprecatedApi.go:93:25:93:43 | call to getUntrustedBytes : slice type | testDeprecatedApi.go:97:13:97:31 | selection of Msg |
99
| testDeprecatedApi.go:104:22:104:41 | call to getUntrustedString : string | testDeprecatedApi.go:105:13:105:20 | selection of Id |
1010
| testDeprecatedApi.go:112:22:112:41 | call to getUntrustedString : string | testDeprecatedApi.go:117:12:117:21 | serialized |
11+
| testDeprecatedApi.go:133:29:133:48 | call to getUntrustedString : string | testDeprecatedApi.go:137:12:137:21 | serialized |
12+
| testDeprecatedApi.go:143:20:143:39 | call to getUntrustedString : string | testDeprecatedApi.go:148:12:148:21 | serialized |
13+
| testDeprecatedApi.go:152:25:152:43 | call to getUntrustedBytes : slice type | testDeprecatedApi.go:157:13:157:36 | index expression |
14+
| testDeprecatedApi.go:161:25:161:43 | call to getUntrustedBytes : slice type | testDeprecatedApi.go:168:13:168:25 | index expression |
1115
| testModernApi.go:11:22:11:41 | call to getUntrustedString : string | testModernApi.go:15:12:15:21 | serialized |
1216
| testModernApi.go:20:22:20:41 | call to getUntrustedString : string | testModernApi.go:26:12:26:21 | serialized |
1317
| testModernApi.go:30:25:30:43 | call to getUntrustedBytes : slice type | testModernApi.go:34:13:34:29 | selection of Description |
@@ -21,3 +25,7 @@
2125
| testModernApi.go:131:25:131:43 | call to getUntrustedBytes : slice type | testModernApi.go:135:13:135:29 | selection of Description |
2226
| testModernApi.go:142:22:142:41 | call to getUntrustedString : string | testModernApi.go:143:13:143:20 | selection of Id |
2327
| testModernApi.go:150:22:150:41 | call to getUntrustedString : string | testModernApi.go:155:12:155:21 | serialized |
28+
| testModernApi.go:190:29:190:48 | call to getUntrustedString : string | testModernApi.go:194:12:194:21 | serialized |
29+
| testModernApi.go:200:20:200:39 | call to getUntrustedString : string | testModernApi.go:205:12:205:21 | serialized |
30+
| testModernApi.go:209:25:209:43 | call to getUntrustedBytes : slice type | testModernApi.go:214:13:214:36 | index expression |
31+
| testModernApi.go:218:25:218:43 | call to getUntrustedBytes : slice type | testModernApi.go:225:13:225:25 | index expression |

ql/test/library-tests/semmle/go/frameworks/Protobuf/protos/query.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ message Query {
1616
}
1717

1818
repeated Alert alerts = 4;
19+
20+
map<int32, string> keyValuePairs = 5;
1921
}
2022

2123
message QuerySuite {

ql/test/library-tests/semmle/go/frameworks/Protobuf/protos/query/query.pb.go

Lines changed: 43 additions & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ql/test/library-tests/semmle/go/frameworks/Protobuf/testDeprecatedApi.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,43 @@ func testSubmessageAliasFalseNegative() {
127127

128128
sinkBytes(serialized) // BAD (but not noticed by our current implementation)
129129
}
130+
131+
func testTaintedMapFieldWrite() {
132+
query := &query.Query{}
133+
query.KeyValuePairs[123] = getUntrustedString()
134+
135+
serialized, _ := proto.Marshal(query)
136+
137+
sinkBytes(serialized) // BAD
138+
}
139+
140+
func testTaintedMapWriteWholeMap() {
141+
query := &query.Query{}
142+
taintedMap := map[int32]string{}
143+
taintedMap[123] = getUntrustedString()
144+
query.KeyValuePairs = taintedMap
145+
146+
serialized, _ := proto.Marshal(query)
147+
148+
sinkBytes(serialized) // BAD
149+
}
150+
151+
func testTaintedMapFieldRead() {
152+
untrustedSerialized := getUntrustedBytes()
153+
query := &query.Query{}
154+
155+
proto.Unmarshal(untrustedSerialized, query)
156+
157+
sinkString(query.KeyValuePairs[123]) // BAD
158+
}
159+
160+
func testTaintedMapFieldReadViaAlias() {
161+
untrustedSerialized := getUntrustedBytes()
162+
query := &query.Query{}
163+
164+
proto.Unmarshal(untrustedSerialized, query)
165+
166+
alias := &query.KeyValuePairs
167+
168+
sinkString((*alias)[123]) // BAD
169+
}

ql/test/library-tests/semmle/go/frameworks/Protobuf/testModernApi.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,3 +184,43 @@ func testMarshalStateFalseNegative() {
184184

185185
sinkBytes(serialized.Buf) // BAD (but not noticed by our current implementation)
186186
}
187+
188+
func testTaintedMapFieldWriteModern() {
189+
query := &query.Query{}
190+
query.KeyValuePairs[123] = getUntrustedString()
191+
192+
serialized, _ := proto.Marshal(query)
193+
194+
sinkBytes(serialized) // BAD
195+
}
196+
197+
func testTaintedMapWriteWholeMapModern() {
198+
query := &query.Query{}
199+
taintedMap := map[int32]string{}
200+
taintedMap[123] = getUntrustedString()
201+
query.KeyValuePairs = taintedMap
202+
203+
serialized, _ := proto.Marshal(query)
204+
205+
sinkBytes(serialized) // BAD
206+
}
207+
208+
func testTaintedMapFieldReadModern() {
209+
untrustedSerialized := getUntrustedBytes()
210+
query := &query.Query{}
211+
212+
proto.Unmarshal(untrustedSerialized, query)
213+
214+
sinkString(query.KeyValuePairs[123]) // BAD
215+
}
216+
217+
func testTaintedMapFieldReadViaAliasModern() {
218+
untrustedSerialized := getUntrustedBytes()
219+
query := &query.Query{}
220+
221+
proto.Unmarshal(untrustedSerialized, query)
222+
223+
alias := &query.KeyValuePairs
224+
225+
sinkString((*alias)[123]) // BAD
226+
}

0 commit comments

Comments
 (0)