Skip to content

Commit e6d11fc

Browse files
author
Sauyon Lee
authored
Merge pull request #475 from sauyon/yaml
Add models for gopkg.in/yaml
2 parents 2be66d1 + 1acbfaa commit e6d11fc

11 files changed

Lines changed: 336 additions & 0 deletions

File tree

change-notes/2021-02-10-yaml.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lgtm,codescanning
2+
* Added support for the [gopkg.in/yaml](https://pkg.go.dev/gopkg.in/yaml.v3) package, which may lead to more results from the security queries.

ql/src/go.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,6 @@ import semmle.go.frameworks.Testing
5858
import semmle.go.frameworks.WebSocket
5959
import semmle.go.frameworks.XNetHtml
6060
import semmle.go.frameworks.XPath
61+
import semmle.go.frameworks.Yaml
6162
import semmle.go.frameworks.Zap
6263
import semmle.go.security.FlowSources
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* Provides classes for working with the [gopkg.in/yaml](https://pkg.go.dev/gopkg.in/yaml.v3) package.
3+
*/
4+
5+
import go
6+
7+
/**
8+
* Provides classes for working with the [gopkg.in/yaml](https://pkg.go.dev/gopkg.in/yaml.v3) package.
9+
*/
10+
module Yaml {
11+
/** Gets a package path for the Yaml package. */
12+
bindingset[result]
13+
string packagePath() { result = package("gopkg.in/yaml", "") }
14+
15+
private class MarshalFunction extends TaintTracking::FunctionModel, MarshalingFunction::Range {
16+
MarshalFunction() { this.hasQualifiedName(packagePath(), "Marshal") }
17+
18+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
19+
input = this.getAnInput() and output = this.getOutput()
20+
}
21+
22+
override DataFlow::FunctionInput getAnInput() { result.isParameter(0) }
23+
24+
override DataFlow::FunctionOutput getOutput() { result.isResult(0) }
25+
26+
override string getFormat() { result = "yaml" }
27+
}
28+
29+
private class UnmarshalFunction extends TaintTracking::FunctionModel, UnmarshalingFunction::Range {
30+
UnmarshalFunction() { this.hasQualifiedName(packagePath(), ["Unmarshal", "UnmarshalStrict"]) }
31+
32+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
33+
input = this.getAnInput() and output = this.getOutput()
34+
}
35+
36+
override DataFlow::FunctionInput getAnInput() { result.isParameter(0) }
37+
38+
override DataFlow::FunctionOutput getOutput() { result.isParameter(1) }
39+
40+
override string getFormat() { result = "yaml" }
41+
}
42+
43+
private class FunctionModels extends TaintTracking::FunctionModel {
44+
FunctionInput inp;
45+
FunctionOutput outp;
46+
47+
FunctionModels() {
48+
this.hasQualifiedName(packagePath(), "NewDecoder") and
49+
(inp.isParameter(0) and outp.isResult())
50+
or
51+
this.hasQualifiedName(packagePath(), "NewEncoder") and
52+
(inp.isResult() and outp.isParameter(0))
53+
or
54+
exists(Method m | this = m |
55+
m.hasQualifiedName(packagePath(), ["Decoder", "Node"], "Decode") and
56+
(inp.isReceiver() and outp.isParameter(0))
57+
or
58+
m.hasQualifiedName(packagePath(), ["Encoder", "Node"], "Encode") and
59+
(inp.isParameter(0) and outp.isReceiver())
60+
or
61+
m.hasQualifiedName(packagePath(), "Node", "SetString") and
62+
(inp.isParameter(0) and outp.isReceiver())
63+
)
64+
}
65+
66+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
67+
input = inp and output = outp
68+
}
69+
}
70+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module codeql-go-tests/frameworks/Yaml
2+
3+
go 1.15
4+
5+
require (
6+
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0
7+
gopkg.in/yaml.v2 v2.4.0
8+
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
9+
)

ql/test/library-tests/semmle/go/frameworks/Yaml/tests.expected

Whitespace-only changes.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import go
2+
import TestUtilities.InlineExpectationsTest
3+
4+
class TaintFunctionModelTest extends InlineExpectationsTest {
5+
TaintFunctionModelTest() { this = "TaintFunctionModelTest" }
6+
7+
override string getARelevantTag() { result = "ttfnmodelstep" }
8+
9+
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
10+
tag = "ttfnmodelstep" and
11+
exists(TaintTracking::FunctionModel model, DataFlow::CallNode call | call = model.getACall() |
12+
call.hasLocationInfo(file, line, _, _, _) and
13+
element = call.toString() and
14+
value = model.getAnInputNode(call) + " -> " + model.getAnOutputNode(call)
15+
)
16+
}
17+
}
18+
19+
class MarshalerTest extends InlineExpectationsTest {
20+
MarshalerTest() { this = "MarshalerTest" }
21+
22+
override string getARelevantTag() { result = "marshaler" }
23+
24+
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
25+
tag = "marshaler" and
26+
exists(MarshalingFunction m, DataFlow::CallNode call | call = m.getACall() |
27+
call.hasLocationInfo(file, line, _, _, _) and
28+
element = call.toString() and
29+
value =
30+
m.getFormat() + ": " + m.getAnInput().getNode(call) + " -> " + m.getOutput().getNode(call)
31+
)
32+
}
33+
}
34+
35+
class UnmarshalerTest extends InlineExpectationsTest {
36+
UnmarshalerTest() { this = "UnmarshalerTest" }
37+
38+
override string getARelevantTag() { result = "unmarshaler" }
39+
40+
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
41+
tag = "unmarshaler" and
42+
exists(UnmarshalingFunction m, DataFlow::CallNode call | call = m.getACall() |
43+
call.hasLocationInfo(file, line, _, _, _) and
44+
element = call.toString() and
45+
value =
46+
m.getFormat() + ": " + m.getAnInput().getNode(call) + " -> " + m.getOutput().getNode(call)
47+
)
48+
}
49+
}

ql/test/library-tests/semmle/go/frameworks/Yaml/vendor/gopkg.in/yaml.v1/stub.go

Lines changed: 16 additions & 0 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/Yaml/vendor/gopkg.in/yaml.v2/stub.go

Lines changed: 50 additions & 0 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/Yaml/vendor/gopkg.in/yaml.v3/stub.go

Lines changed: 89 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0
2+
## explicit
3+
gopkg.in/yaml.v1
4+
# gopkg.in/yaml.v2 v2.4.0
5+
## explicit
6+
gopkg.in/yaml.v2
7+
# gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
8+
## explicit
9+
gopkg.in/yaml.v3

0 commit comments

Comments
 (0)