mirror of
https://github.com/github/codeql.git
synced 2026-01-29 14:23:03 +01:00
Add models for gopkg.in/yaml
This commit is contained in:
2
change-notes/2021-02-10-yaml.md
Normal file
2
change-notes/2021-02-10-yaml.md
Normal file
@@ -0,0 +1,2 @@
|
||||
lgtm,codescanning
|
||||
* 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.
|
||||
@@ -58,5 +58,6 @@ import semmle.go.frameworks.Testing
|
||||
import semmle.go.frameworks.WebSocket
|
||||
import semmle.go.frameworks.XNetHtml
|
||||
import semmle.go.frameworks.XPath
|
||||
import semmle.go.frameworks.Yaml
|
||||
import semmle.go.frameworks.Zap
|
||||
import semmle.go.security.FlowSources
|
||||
|
||||
70
ql/src/semmle/go/frameworks/Yaml.qll
Normal file
70
ql/src/semmle/go/frameworks/Yaml.qll
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Provides classes for working with the [gopkg.in/yaml](https://pkg.go.dev/gopkg.in/yaml.v3) package.
|
||||
*/
|
||||
|
||||
import go
|
||||
|
||||
/**
|
||||
* Provides classes for working with the [gopkg.in/yaml](https://pkg.go.dev/gopkg.in/yaml.v3) package.
|
||||
*/
|
||||
module Yaml {
|
||||
/** Gets a package path for the Yaml package. */
|
||||
bindingset[result]
|
||||
string packagePath() { result = package("gopkg.in/yaml", "") }
|
||||
|
||||
private class MarshalFunction extends TaintTracking::FunctionModel, MarshalingFunction::Range {
|
||||
MarshalFunction() { this.hasQualifiedName(packagePath(), "Marshal") }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input = this.getAnInput() and output = this.getOutput()
|
||||
}
|
||||
|
||||
override DataFlow::FunctionInput getAnInput() { result.isParameter(0) }
|
||||
|
||||
override DataFlow::FunctionOutput getOutput() { result.isResult(0) }
|
||||
|
||||
override string getFormat() { result = "yaml" }
|
||||
}
|
||||
|
||||
private class UnmarshalFunction extends TaintTracking::FunctionModel, UnmarshalingFunction::Range {
|
||||
UnmarshalFunction() { this.hasQualifiedName(packagePath(), ["Unmarshal", "UnmarshalStrict"]) }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input = this.getAnInput() and output = this.getOutput()
|
||||
}
|
||||
|
||||
override DataFlow::FunctionInput getAnInput() { result.isParameter(0) }
|
||||
|
||||
override DataFlow::FunctionOutput getOutput() { result.isParameter(1) }
|
||||
|
||||
override string getFormat() { result = "yaml" }
|
||||
}
|
||||
|
||||
private class FunctionModels extends TaintTracking::FunctionModel {
|
||||
FunctionInput inp;
|
||||
FunctionOutput outp;
|
||||
|
||||
FunctionModels() {
|
||||
this.hasQualifiedName(packagePath(), "NewDecoder") and
|
||||
(inp.isParameter(0) and outp.isResult())
|
||||
or
|
||||
this.hasQualifiedName(packagePath(), "NewEncoder") and
|
||||
(inp.isResult() and outp.isParameter(0))
|
||||
or
|
||||
exists(Method m | this = m |
|
||||
m.hasQualifiedName(packagePath(), ["Decoder", "Node"], "Decode") and
|
||||
(inp.isReceiver() and outp.isParameter(0))
|
||||
or
|
||||
m.hasQualifiedName(packagePath(), ["Encoder", "Node"], "Encode") and
|
||||
(inp.isParameter(0) and outp.isReceiver())
|
||||
or
|
||||
m.hasQualifiedName(packagePath(), "Node", "SetString") and
|
||||
(inp.isParameter(0) and outp.isReceiver())
|
||||
)
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input = inp and output = outp
|
||||
}
|
||||
}
|
||||
}
|
||||
9
ql/test/library-tests/semmle/go/frameworks/Yaml/go.mod
Normal file
9
ql/test/library-tests/semmle/go/frameworks/Yaml/go.mod
Normal file
@@ -0,0 +1,9 @@
|
||||
module codeql-go-tests/frameworks/Yaml
|
||||
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||
)
|
||||
49
ql/test/library-tests/semmle/go/frameworks/Yaml/tests.ql
Normal file
49
ql/test/library-tests/semmle/go/frameworks/Yaml/tests.ql
Normal file
@@ -0,0 +1,49 @@
|
||||
import go
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
class TaintFunctionModelTest extends InlineExpectationsTest {
|
||||
TaintFunctionModelTest() { this = "TaintFunctionModelTest" }
|
||||
|
||||
override string getARelevantTag() { result = "ttfnmodelstep" }
|
||||
|
||||
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
|
||||
tag = "ttfnmodelstep" and
|
||||
exists(TaintTracking::FunctionModel model, DataFlow::CallNode call | call = model.getACall() |
|
||||
call.hasLocationInfo(file, line, _, _, _) and
|
||||
element = call.toString() and
|
||||
value = model.getAnInputNode(call) + " -> " + model.getAnOutputNode(call)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class MarshalerTest extends InlineExpectationsTest {
|
||||
MarshalerTest() { this = "MarshalerTest" }
|
||||
|
||||
override string getARelevantTag() { result = "marshaler" }
|
||||
|
||||
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
|
||||
tag = "marshaler" and
|
||||
exists(MarshalingFunction m, DataFlow::CallNode call | call = m.getACall() |
|
||||
call.hasLocationInfo(file, line, _, _, _) and
|
||||
element = call.toString() and
|
||||
value =
|
||||
m.getFormat() + ": " + m.getAnInput().getNode(call) + " -> " + m.getOutput().getNode(call)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class UnmarshalerTest extends InlineExpectationsTest {
|
||||
UnmarshalerTest() { this = "UnmarshalerTest" }
|
||||
|
||||
override string getARelevantTag() { result = "unmarshaler" }
|
||||
|
||||
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
|
||||
tag = "unmarshaler" and
|
||||
exists(UnmarshalingFunction m, DataFlow::CallNode call | call = m.getACall() |
|
||||
call.hasLocationInfo(file, line, _, _, _) and
|
||||
element = call.toString() and
|
||||
value =
|
||||
m.getFormat() + ": " + m.getAnInput().getNode(call) + " -> " + m.getOutput().getNode(call)
|
||||
)
|
||||
}
|
||||
}
|
||||
16
ql/test/library-tests/semmle/go/frameworks/Yaml/vendor/gopkg.in/yaml.v1/stub.go
generated
vendored
Normal file
16
ql/test/library-tests/semmle/go/frameworks/Yaml/vendor/gopkg.in/yaml.v1/stub.go
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
// Code generated by depstubber. DO NOT EDIT.
|
||||
// This is a simple stub for gopkg.in/yaml.v1, strictly for use in testing.
|
||||
|
||||
// See the LICENSE file for information about the licensing of the original library.
|
||||
// Source: gopkg.in/yaml.v1 (exports: ; functions: Marshal,Unmarshal)
|
||||
|
||||
// Package yaml is a stub of gopkg.in/yaml.v1, generated by depstubber.
|
||||
package yaml
|
||||
|
||||
func Marshal(_ interface{}) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func Unmarshal(_ []byte, _ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
50
ql/test/library-tests/semmle/go/frameworks/Yaml/vendor/gopkg.in/yaml.v2/stub.go
generated
vendored
Normal file
50
ql/test/library-tests/semmle/go/frameworks/Yaml/vendor/gopkg.in/yaml.v2/stub.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
// Code generated by depstubber. DO NOT EDIT.
|
||||
// This is a simple stub for gopkg.in/yaml.v2, strictly for use in testing.
|
||||
|
||||
// See the LICENSE file for information about the licensing of the original library.
|
||||
// Source: gopkg.in/yaml.v2 (exports: ; functions: Marshal,NewDecoder,NewEncoder,Unmarshal,UnmarshalStrict)
|
||||
|
||||
// Package yaml is a stub of gopkg.in/yaml.v2, generated by depstubber.
|
||||
package yaml
|
||||
|
||||
import (
|
||||
io "io"
|
||||
)
|
||||
|
||||
type Decoder struct{}
|
||||
|
||||
func (_ *Decoder) Decode(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Decoder) SetStrict(_ bool) {}
|
||||
|
||||
type Encoder struct{}
|
||||
|
||||
func (_ *Encoder) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Encoder) Encode(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Marshal(_ interface{}) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func NewDecoder(_ io.Reader) *Decoder {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewEncoder(_ io.Writer) *Encoder {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Unmarshal(_ []byte, _ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func UnmarshalStrict(_ []byte, _ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
89
ql/test/library-tests/semmle/go/frameworks/Yaml/vendor/gopkg.in/yaml.v3/stub.go
generated
vendored
Normal file
89
ql/test/library-tests/semmle/go/frameworks/Yaml/vendor/gopkg.in/yaml.v3/stub.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
// Code generated by depstubber. DO NOT EDIT.
|
||||
// This is a simple stub for gopkg.in/yaml.v3, strictly for use in testing.
|
||||
|
||||
// See the LICENSE file for information about the licensing of the original library.
|
||||
// Source: gopkg.in/yaml.v3 (exports: Node; functions: Marshal,NewDecoder,NewEncoder,Unmarshal)
|
||||
|
||||
// Package yaml is a stub of gopkg.in/yaml.v3, generated by depstubber.
|
||||
package yaml
|
||||
|
||||
import (
|
||||
io "io"
|
||||
)
|
||||
|
||||
type Decoder struct{}
|
||||
|
||||
func (_ *Decoder) Decode(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Decoder) KnownFields(_ bool) {}
|
||||
|
||||
type Encoder struct{}
|
||||
|
||||
func (_ *Encoder) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Encoder) Encode(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Encoder) SetIndent(_ int) {}
|
||||
|
||||
type Kind uint32
|
||||
|
||||
func Marshal(_ interface{}) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func NewDecoder(_ io.Reader) *Decoder {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewEncoder(_ io.Writer) *Encoder {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Node struct {
|
||||
Kind Kind
|
||||
Style Style
|
||||
Tag string
|
||||
Value string
|
||||
Anchor string
|
||||
Alias *Node
|
||||
Content []*Node
|
||||
HeadComment string
|
||||
LineComment string
|
||||
FootComment string
|
||||
Line int
|
||||
Column int
|
||||
}
|
||||
|
||||
func (_ *Node) Decode(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Node) Encode(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Node) IsZero() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Node) LongTag() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Node) SetString(_ string) {}
|
||||
|
||||
func (_ *Node) ShortTag() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type Style uint32
|
||||
|
||||
func Unmarshal(_ []byte, _ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
9
ql/test/library-tests/semmle/go/frameworks/Yaml/vendor/modules.txt
vendored
Normal file
9
ql/test/library-tests/semmle/go/frameworks/Yaml/vendor/modules.txt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
# gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0
|
||||
## explicit
|
||||
gopkg.in/yaml.v1
|
||||
# gopkg.in/yaml.v2 v2.4.0
|
||||
## explicit
|
||||
gopkg.in/yaml.v2
|
||||
# gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||
## explicit
|
||||
gopkg.in/yaml.v3
|
||||
41
ql/test/library-tests/semmle/go/frameworks/Yaml/yaml.go
Normal file
41
ql/test/library-tests/semmle/go/frameworks/Yaml/yaml.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
yaml1 "gopkg.in/yaml.v1"
|
||||
yaml2 "gopkg.in/yaml.v2"
|
||||
yaml3 "gopkg.in/yaml.v3"
|
||||
"io"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var in, out interface{}
|
||||
var inb []byte
|
||||
|
||||
out, _ = yaml1.Marshal(in) // $marshaler=yaml: in -> ... = ...[0] $ttfnmodelstep=in -> ... = ...[0]
|
||||
yaml1.Unmarshal(inb, out) // $unmarshaler=yaml: inb -> definition of out $ttfnmodelstep=inb -> definition of out
|
||||
|
||||
out, _ = yaml2.Marshal(in) // $marshaler=yaml: in -> ... = ...[0] $ttfnmodelstep=in -> ... = ...[0]
|
||||
yaml2.Unmarshal(inb, out) // $unmarshaler=yaml: inb -> definition of out $ttfnmodelstep=inb -> definition of out
|
||||
yaml2.UnmarshalStrict(inb, out) // $unmarshaler=yaml: inb -> definition of out $ttfnmodelstep=inb -> definition of out
|
||||
|
||||
var r io.Reader
|
||||
d := yaml2.NewDecoder(r) // $ttfnmodelstep=r -> call to NewDecoder
|
||||
d.Decode(out) // $ttfnmodelstep=d -> definition of out
|
||||
|
||||
var w io.Writer
|
||||
e := yaml2.NewEncoder(w) // $ttfnmodelstep=definition of e -> definition of w
|
||||
e.Encode(in) // $ttfnmodelstep=in -> definition of e
|
||||
|
||||
out, _ = yaml3.Marshal(in) // $marshaler=yaml: in -> ... = ...[0] $ttfnmodelstep=in -> ... = ...[0]
|
||||
yaml3.Unmarshal(inb, out) // $unmarshaler=yaml: inb -> definition of out $ttfnmodelstep=inb -> definition of out
|
||||
|
||||
d1 := yaml3.NewDecoder(r) // $ttfnmodelstep=r -> call to NewDecoder
|
||||
d1.Decode(out) // $ttfnmodelstep=d1 -> definition of out
|
||||
|
||||
e1 := yaml3.NewEncoder(w) // $ttfnmodelstep=definition of e1 -> definition of w
|
||||
e1.Encode(in) // $ttfnmodelstep=in -> definition of e1
|
||||
|
||||
var n1 yaml3.Node
|
||||
n1.Decode(out) // $ttfnmodelstep=n1 -> definition of out
|
||||
n1.Encode(in) // $ttfnmodelstep=in -> definition of n1
|
||||
}
|
||||
Reference in New Issue
Block a user