We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
2 parents 5a18f1f + dd87b1a commit f21439aCopy full SHA for f21439a
18 files changed
go/ql/lib/ext/os.model.yml
@@ -53,6 +53,7 @@ extensions:
53
- ["os", "", False, "Open", "", "", "ReturnValue[0]", "file", "manual"]
54
- ["os", "", False, "OpenFile", "", "", "ReturnValue[0]", "file", "manual"]
55
- ["os", "", False, "ReadFile", "", "", "ReturnValue[0]", "file", "manual"]
56
+ - ["os", "", False, "Stdin", "", "", "", "stdin", "manual"]
57
- ["os", "", False, "UserCacheDir", "", "", "ReturnValue[0]", "environment", "manual"]
58
- ["os", "", False, "UserConfigDir", "", "", "ReturnValue[0]", "environment", "manual"]
59
- ["os", "", False, "UserHomeDir", "", "", "ReturnValue[0]", "environment", "manual"]
go/ql/lib/semmle/go/dataflow/ExternalFlow.qll
@@ -38,7 +38,8 @@
38
* first 6 columns, and the `output` column specifies how data leaves the
39
* element selected by the first 6 columns. An `input` can be either "",
40
* "Argument[n]", or "Argument[n1..n2]":
41
- * - "": Selects a write to the selected element in case this is a field.
+ * - "": Selects a write to the selected element in case this is a field or
42
+ * package-level variable.
43
* - "Argument[n]": Selects an argument in a call to the selected element.
44
* The arguments are zero-indexed, and `receiver` specifies the receiver.
45
* - "Argument[n1..n2]": Similar to "Argument[n]" but selects any argument
@@ -47,7 +48,7 @@
47
48
* An `output` can be either "", "Argument[n]", "Argument[n1..n2]", "Parameter",
49
* "Parameter[n]", "Parameter[n1..n2]", , "ReturnValue", "ReturnValue[n]", or
50
* "ReturnValue[n1..n2]":
- * - "": Selects a read of a selected field.
51
+ * - "": Selects a read of a selected field or package-level variable.
52
* - "Argument[n]": Selects the post-update value of an argument in a call to the
* selected element. That is, the value of the argument after the call returns.
go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll
@@ -399,6 +399,13 @@ module SourceSinkInterpretationInput implements
399
c = "" and
400
pragma[only_bind_into](e) = getElementWithQualifier(frn.getField(), frn.getBase())
401
)
402
+ or
403
+ // A package-scope (or universe-scope) variable
404
+ exists(Variable v | not v instanceof Field |
405
+ c = "" and
406
+ n.(DataFlow::ReadNode).reads(v) and
407
+ pragma[only_bind_into](e).asEntity() = v
408
+ )
409
410
}
411
@@ -420,6 +427,17 @@ module SourceSinkInterpretationInput implements
420
427
fw.writesField(base, f, node.asNode()) and
421
428
pragma[only_bind_into](e) = getElementWithQualifier(f, base)
422
429
430
431
432
+ exists(Node n, SourceOrSinkElement e, DataFlow::Write w, Variable v |
433
+ n = node.asNode() and
434
+ e = mid.asElement() and
435
+ not v instanceof Field
436
+ |
437
438
+ w.writes(v, n) and
439
440
423
441
424
442
425
443
go/ql/lib/semmle/go/frameworks/stdlib/Os.qll
@@ -43,12 +43,4 @@ module Os {
input = inp and output = outp
46
-
- private class Stdin extends SourceNode {
- Stdin() {
- exists(Variable osStdin | osStdin.hasQualifiedName("os", "Stdin") | this = osStdin.getARead())
- }
- override string getThreatModel() { result = "stdin" }
go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/completetest.ext.yml
@@ -35,10 +35,12 @@ extensions:
35
pack: codeql/go-all
36
extensible: sourceModel
37
data:
+ - ["github.com/nonexistent/test", "", False, "SourceVariable", "", "", "", "qltest", "manual"]
- ["github.com/nonexistent/test", "A", False, "Src1", "", "", "ReturnValue", "qltest", "manual"]
- addsTo:
extensible: sinkModel
+ - ["github.com/nonexistent/test", "", False, "SinkVariable", "", "", "", "qltest", "manual"]
- ["github.com/nonexistent/test", "B", False, "Sink1", "", "", "Argument[0]", "qltest", "manual"]
- ["github.com/nonexistent/test", "B", False, "SinkManyArgs", "", "", "Argument[0..2]", "qltest", "manual"]
go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/sinks.expected
@@ -43,3 +43,4 @@ invalidModelRow
| test.go:199:17:199:20 | arg1 | qltest |
| test.go:199:23:199:26 | arg2 | qltest |
| test.go:199:29:199:32 | arg3 | qltest |
+| test.go:202:22:202:25 | temp | qltest |
go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/sinks.ext.yml
@@ -3,6 +3,7 @@ extensions:
3
4
5
6
7
8
- ["github.com/nonexistent/test", "B", False, "SinkMethod", "", "", "Argument[receiver]", "qltest", "manual"]
9
go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/srcs.expected
@@ -21,3 +21,4 @@ invalidModelRow
21
| test.go:183:17:183:24 | call to Src1 | qltest |
22
| test.go:187:24:187:31 | call to Src1 | qltest |
23
| test.go:191:24:191:31 | call to Src1 | qltest |
24
+| test.go:201:10:201:28 | selection of SourceVariable | qltest |
go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/srcs.ext.yml
@@ -3,9 +3,10 @@ extensions:
- ["github.com/nonexistent/test", "A", False, "Src2", "", "", "ReturnValue", "qltest", "manual"]
- ["github.com/nonexistent/test", "A", True, "Src2", "", "", "ReturnValue", "qltest-w-subtypes", "manual"]
10
- ["github.com/nonexistent/test", "A", False, "SrcArg", "", "", "Argument[0]", "qltest-arg", "manual"]
11
- ["github.com/nonexistent/test", "A", False, "Src3", "", "", "ReturnValue[0]", "qltest", "manual"]
- - ["github.com/nonexistent/test", "A", True, "Src3", "", "", "ReturnValue[1]", "qltest-w-subtypes", "manual"]
12
+ - ["github.com/nonexistent/test", "A", True, "Src3", "", "", "ReturnValue[1]", "qltest-w-subtypes", "manual"]
go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/test.go
@@ -197,6 +197,9 @@ func simpleflow() {
197
arg3 := src
198
arg4 := src
199
b.SinkManyArgs(arg1, arg2, arg3, arg4) // $ hasTaintFlow="arg1" hasTaintFlow="arg2" hasTaintFlow="arg3"
200
+
201
+ temp := test.SourceVariable
202
+ test.SinkVariable = temp // $ hasTaintFlow="temp"
203
204
205
type mapstringstringtype map[string]string
0 commit comments