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

Commit 8d7cbe3

Browse files
authored
Merge pull request #323 from gagliardetto/standard-lib-pt-8
Add taint-tracking for packages in `encoding/*`
2 parents 3ba8557 + 4c25370 commit 8d7cbe3

26 files changed

+1966
-47
lines changed

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

Lines changed: 12 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,18 @@ import semmle.go.frameworks.stdlib.CompressZlib
1515
import semmle.go.frameworks.stdlib.Mime
1616
import semmle.go.frameworks.stdlib.MimeMultipart
1717
import semmle.go.frameworks.stdlib.MimeQuotedprintable
18+
import semmle.go.frameworks.stdlib.Encoding
19+
import semmle.go.frameworks.stdlib.EncodingAscii85
20+
import semmle.go.frameworks.stdlib.EncodingAsn1
21+
import semmle.go.frameworks.stdlib.EncodingBase32
22+
import semmle.go.frameworks.stdlib.EncodingBase64
23+
import semmle.go.frameworks.stdlib.EncodingBinary
24+
import semmle.go.frameworks.stdlib.EncodingCsv
25+
import semmle.go.frameworks.stdlib.EncodingGob
26+
import semmle.go.frameworks.stdlib.EncodingHex
27+
import semmle.go.frameworks.stdlib.EncodingJson
28+
import semmle.go.frameworks.stdlib.EncodingPem
29+
import semmle.go.frameworks.stdlib.EncodingXml
1830
import semmle.go.frameworks.stdlib.Path
1931
import semmle.go.frameworks.stdlib.PathFilepath
2032
import semmle.go.frameworks.stdlib.Reflect
@@ -697,53 +709,6 @@ module Log {
697709
}
698710
}
699711

700-
/** Provides models of some functions in the `encoding/json` package. */
701-
module EncodingJson {
702-
/** The `Marshal` or `MarshalIndent` function in the `encoding/json` package. */
703-
class MarshalFunction extends TaintTracking::FunctionModel, MarshalingFunction::Range {
704-
MarshalFunction() {
705-
this.hasQualifiedName("encoding/json", "Marshal") or
706-
this.hasQualifiedName("encoding/json", "MarshalIndent")
707-
}
708-
709-
override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) {
710-
inp = getAnInput() and outp = getOutput()
711-
}
712-
713-
override FunctionInput getAnInput() { result.isParameter(0) }
714-
715-
override FunctionOutput getOutput() { result.isResult(0) }
716-
717-
override string getFormat() { result = "JSON" }
718-
}
719-
720-
private class UnmarshalFunction extends TaintTracking::FunctionModel, UnmarshalingFunction::Range {
721-
UnmarshalFunction() { this.hasQualifiedName("encoding/json", "Unmarshal") }
722-
723-
override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) {
724-
inp = getAnInput() and outp = getOutput()
725-
}
726-
727-
override FunctionInput getAnInput() { result.isParameter(0) }
728-
729-
override FunctionOutput getOutput() { result.isParameter(1) }
730-
731-
override string getFormat() { result = "JSON" }
732-
}
733-
}
734-
735-
/** Provides models of some functions in the `encoding/hex` package. */
736-
module EncodingHex {
737-
private class DecodeStringFunction extends TaintTracking::FunctionModel {
738-
DecodeStringFunction() { this.hasQualifiedName("encoding/hex", "DecodeString") }
739-
740-
override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) {
741-
inp.isParameter(0) and
742-
outp.isResult(0)
743-
}
744-
}
745-
}
746-
747712
/** Provides models of some functions in the `crypto/cipher` package. */
748713
module CryptoCipher {
749714
private class AeadOpenFunction extends TaintTracking::FunctionModel, Method {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `encoding` package.
3+
*/
4+
5+
import go
6+
7+
/** Provides models of commonly used functions in the `encoding` package. */
8+
module Encoding {
9+
private class MethodModels extends TaintTracking::FunctionModel, Method {
10+
FunctionInput inp;
11+
FunctionOutput outp;
12+
13+
MethodModels() {
14+
// signature: func (BinaryMarshaler).MarshalBinary() (data []byte, err error)
15+
this.implements("encoding", "BinaryMarshaler", "MarshalBinary") and
16+
(inp.isReceiver() and outp.isResult(0))
17+
or
18+
// signature: func (TextMarshaler).MarshalText() (text []byte, err error)
19+
this.implements("encoding", "TextMarshaler", "MarshalText") and
20+
(inp.isReceiver() and outp.isResult(0))
21+
or
22+
// signature: func (BinaryUnmarshaler).UnmarshalBinary(data []byte) error
23+
this.implements("encoding", "BinaryUnmarshaler", "UnmarshalBinary") and
24+
(inp.isParameter(0) and outp.isReceiver())
25+
or
26+
// signature: func (TextUnmarshaler).UnmarshalText(text []byte) error
27+
this.implements("encoding", "TextUnmarshaler", "UnmarshalText") and
28+
(inp.isParameter(0) and outp.isReceiver())
29+
}
30+
31+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
32+
input = inp and output = outp
33+
}
34+
}
35+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `encoding/ascii85` package.
3+
*/
4+
5+
import go
6+
7+
/** Provides models of commonly used functions in the `encoding/ascii85` package. */
8+
module EncodingAscii85 {
9+
private class FunctionModels extends TaintTracking::FunctionModel {
10+
FunctionInput inp;
11+
FunctionOutput outp;
12+
13+
FunctionModels() {
14+
// signature: func Decode(dst []byte, src []byte, flush bool) (ndst int, nsrc int, err error)
15+
hasQualifiedName("encoding/ascii85", "Decode") and
16+
(inp.isParameter(1) and outp.isParameter(0))
17+
or
18+
// signature: func NewDecoder(r io.Reader) io.Reader
19+
hasQualifiedName("encoding/ascii85", "NewDecoder") and
20+
(inp.isParameter(0) and outp.isResult())
21+
}
22+
23+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
24+
input = inp and output = outp
25+
}
26+
}
27+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `encoding/asn1` package.
3+
*/
4+
5+
import go
6+
7+
/** Provides models of commonly used functions in the `encoding/asn1` package. */
8+
module EncodingAsn1 {
9+
/** The `Marshal` or `MarshalWithParams` function in the `encoding/asn1` package. */
10+
private class MarshalFunction extends MarshalingFunction::Range {
11+
MarshalFunction() {
12+
hasQualifiedName("encoding/asn1", "Marshal") or
13+
hasQualifiedName("encoding/asn1", "MarshalWithParams")
14+
}
15+
16+
override FunctionInput getAnInput() { result.isParameter(0) }
17+
18+
override FunctionOutput getOutput() { result.isResult(0) }
19+
20+
override string getFormat() { result = "ASN1" }
21+
}
22+
23+
/** The `Unmarshal` or `UnmarshalWithParams` function in the `encoding/asn1` package. */
24+
private class UnmarshalFunction extends UnmarshalingFunction::Range {
25+
UnmarshalFunction() {
26+
hasQualifiedName("encoding/asn1", "Unmarshal") or
27+
hasQualifiedName("encoding/asn1", "UnmarshalWithParams")
28+
}
29+
30+
override FunctionInput getAnInput() { result.isParameter(0) }
31+
32+
override FunctionOutput getOutput() { result.isParameter(1) }
33+
34+
override string getFormat() { result = "ASN1" }
35+
}
36+
37+
private class FunctionModels extends TaintTracking::FunctionModel {
38+
FunctionInput inp;
39+
FunctionOutput outp;
40+
41+
FunctionModels() {
42+
// signature: func Marshal(val interface{}) ([]byte, error)
43+
hasQualifiedName("encoding/asn1", "Marshal") and
44+
(inp.isParameter(0) and outp.isResult(0))
45+
or
46+
// signature: func MarshalWithParams(val interface{}, params string) ([]byte, error)
47+
hasQualifiedName("encoding/asn1", "MarshalWithParams") and
48+
(inp.isParameter(_) and outp.isResult(0))
49+
or
50+
// signature: func Unmarshal(b []byte, val interface{}) (rest []byte, err error)
51+
hasQualifiedName("encoding/asn1", "Unmarshal") and
52+
(
53+
inp.isParameter(0) and
54+
(outp.isParameter(1) or outp.isResult(0))
55+
)
56+
or
57+
// signature: func UnmarshalWithParams(b []byte, val interface{}, params string) (rest []byte, err error)
58+
hasQualifiedName("encoding/asn1", "UnmarshalWithParams") and
59+
(
60+
inp.isParameter([0, 2]) and
61+
(outp.isParameter(1) or outp.isResult(0))
62+
)
63+
}
64+
65+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
66+
input = inp and output = outp
67+
}
68+
}
69+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `encoding/base32` package.
3+
*/
4+
5+
import go
6+
7+
/** Provides models of commonly used functions in the `encoding/base32` package. */
8+
module EncodingBase32 {
9+
private class FunctionModels extends TaintTracking::FunctionModel {
10+
FunctionInput inp;
11+
FunctionOutput outp;
12+
13+
FunctionModels() {
14+
// signature: func NewDecoder(enc *Encoding, r io.Reader) io.Reader
15+
hasQualifiedName("encoding/base32", "NewDecoder") and
16+
(inp.isParameter(1) and outp.isResult())
17+
}
18+
19+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
20+
input = inp and output = outp
21+
}
22+
}
23+
24+
private class MethodModels extends TaintTracking::FunctionModel, Method {
25+
FunctionInput inp;
26+
FunctionOutput outp;
27+
28+
MethodModels() {
29+
// signature: func (*Encoding).Decode(dst []byte, src []byte) (n int, err error)
30+
this.hasQualifiedName("encoding/base32", "Encoding", "Decode") and
31+
(inp.isParameter(1) and outp.isParameter(0))
32+
or
33+
// signature: func (*Encoding).DecodeString(s string) ([]byte, error)
34+
this.hasQualifiedName("encoding/base32", "Encoding", "DecodeString") and
35+
(inp.isParameter(0) and outp.isResult(0))
36+
}
37+
38+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
39+
input = inp and output = outp
40+
}
41+
}
42+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `encoding/base64` package.
3+
*/
4+
5+
import go
6+
7+
/** Provides models of commonly used functions in the `encoding/base64` package. */
8+
module EncodingBase64 {
9+
private class FunctionModels extends TaintTracking::FunctionModel {
10+
FunctionInput inp;
11+
FunctionOutput outp;
12+
13+
FunctionModels() {
14+
// signature: func NewDecoder(enc *Encoding, r io.Reader) io.Reader
15+
hasQualifiedName("encoding/base64", "NewDecoder") and
16+
(inp.isParameter(1) and outp.isResult())
17+
}
18+
19+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
20+
input = inp and output = outp
21+
}
22+
}
23+
24+
private class MethodModels extends TaintTracking::FunctionModel, Method {
25+
FunctionInput inp;
26+
FunctionOutput outp;
27+
28+
MethodModels() {
29+
// signature: func (*Encoding).Decode(dst []byte, src []byte) (n int, err error)
30+
this.hasQualifiedName("encoding/base64", "Encoding", "Decode") and
31+
(inp.isParameter(1) and outp.isParameter(0))
32+
or
33+
// signature: func (*Encoding).DecodeString(s string) ([]byte, error)
34+
this.hasQualifiedName("encoding/base64", "Encoding", "DecodeString") and
35+
(inp.isParameter(0) and outp.isResult(0))
36+
}
37+
38+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
39+
input = inp and output = outp
40+
}
41+
}
42+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `encoding/binary` package.
3+
*/
4+
5+
import go
6+
7+
/** Provides models of commonly used functions in the `encoding/binary` package. */
8+
module EncodingBinary {
9+
private class FunctionModels extends TaintTracking::FunctionModel {
10+
FunctionInput inp;
11+
FunctionOutput outp;
12+
13+
FunctionModels() {
14+
// signature: func Read(r io.Reader, order ByteOrder, data interface{}) error
15+
hasQualifiedName("encoding/binary", "Read") and
16+
(inp.isParameter(0) and outp.isParameter(2))
17+
or
18+
// signature: func Write(w io.Writer, order ByteOrder, data interface{}) error
19+
hasQualifiedName("encoding/binary", "Write") and
20+
(inp.isParameter(2) and outp.isParameter(0))
21+
}
22+
23+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
24+
input = inp and output = outp
25+
}
26+
}
27+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `encoding/csv` package.
3+
*/
4+
5+
import go
6+
7+
/** Provides models of commonly used functions in the `encoding/csv` package. */
8+
module EncodingCsv {
9+
private class FunctionModels extends TaintTracking::FunctionModel {
10+
FunctionInput inp;
11+
FunctionOutput outp;
12+
13+
FunctionModels() {
14+
// signature: func NewReader(r io.Reader) *Reader
15+
hasQualifiedName("encoding/csv", "NewReader") and
16+
(inp.isParameter(0) and outp.isResult())
17+
or
18+
// signature: func NewWriter(w io.Writer) *Writer
19+
hasQualifiedName("encoding/csv", "NewWriter") and
20+
(inp.isResult() and outp.isParameter(0))
21+
}
22+
23+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
24+
input = inp and output = outp
25+
}
26+
}
27+
28+
private class MethodModels extends TaintTracking::FunctionModel, Method {
29+
FunctionInput inp;
30+
FunctionOutput outp;
31+
32+
MethodModels() {
33+
// signature: func (*Reader).Read() (record []string, err error)
34+
this.hasQualifiedName("encoding/csv", "Reader", "Read") and
35+
(inp.isReceiver() and outp.isResult(0))
36+
or
37+
// signature: func (*Reader).ReadAll() (records [][]string, err error)
38+
this.hasQualifiedName("encoding/csv", "Reader", "ReadAll") and
39+
(inp.isReceiver() and outp.isResult(0))
40+
or
41+
// signature: func (*Writer).Write(record []string) error
42+
this.hasQualifiedName("encoding/csv", "Writer", "Write") and
43+
(inp.isParameter(0) and outp.isReceiver())
44+
or
45+
// signature: func (*Writer).WriteAll(records [][]string) error
46+
this.hasQualifiedName("encoding/csv", "Writer", "WriteAll") and
47+
(inp.isParameter(0) and outp.isReceiver())
48+
}
49+
50+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
51+
input = inp and output = outp
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)