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

Commit 24c23ba

Browse files
committed
Add taint-tracking for encoding/json
1 parent f5fc949 commit 24c23ba

File tree

3 files changed

+367
-0
lines changed

3 files changed

+367
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import semmle.go.frameworks.stdlib.EncodingBinary
2424
import semmle.go.frameworks.stdlib.EncodingCsv
2525
import semmle.go.frameworks.stdlib.EncodingGob
2626
import semmle.go.frameworks.stdlib.EncodingHex
27+
import semmle.go.frameworks.stdlib.EncodingJson
2728
import semmle.go.frameworks.stdlib.Path
2829
import semmle.go.frameworks.stdlib.PathFilepath
2930
import semmle.go.frameworks.stdlib.Reflect
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `encoding/json` package.
3+
*/
4+
5+
import go
6+
7+
/** Provides models of commonly used functions in the `encoding/json` package. */
8+
module EncodingJson {
9+
private class FunctionModels extends TaintTracking::FunctionModel {
10+
FunctionInput inp;
11+
FunctionOutput outp;
12+
13+
FunctionModels() {
14+
// signature: func Compact(dst *bytes.Buffer, src []byte) error
15+
hasQualifiedName("encoding/json", "Compact") and
16+
(inp.isParameter(1) and outp.isParameter(0))
17+
or
18+
// signature: func HTMLEscape(dst *bytes.Buffer, src []byte)
19+
hasQualifiedName("encoding/json", "HTMLEscape") and
20+
(inp.isParameter(1) and outp.isParameter(0))
21+
or
22+
// signature: func Indent(dst *bytes.Buffer, src []byte, prefix string, indent string) error
23+
hasQualifiedName("encoding/json", "Indent") and
24+
(inp.isParameter([1, 2, 3]) and outp.isParameter(0))
25+
or
26+
// signature: func Marshal(v interface{}) ([]byte, error)
27+
hasQualifiedName("encoding/json", "Marshal") and
28+
(inp.isParameter(0) and outp.isResult(0))
29+
or
30+
// signature: func MarshalIndent(v interface{}, prefix string, indent string) ([]byte, error)
31+
hasQualifiedName("encoding/json", "MarshalIndent") and
32+
(inp.isParameter(_) and outp.isResult(0))
33+
or
34+
// signature: func NewDecoder(r io.Reader) *Decoder
35+
hasQualifiedName("encoding/json", "NewDecoder") and
36+
(inp.isParameter(0) and outp.isResult())
37+
or
38+
// signature: func NewEncoder(w io.Writer) *Encoder
39+
hasQualifiedName("encoding/json", "NewEncoder") and
40+
(inp.isResult() and outp.isParameter(0))
41+
or
42+
// signature: func Unmarshal(data []byte, v interface{}) error
43+
hasQualifiedName("encoding/json", "Unmarshal") and
44+
(inp.isParameter(0) and outp.isParameter(1))
45+
}
46+
47+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
48+
input = inp and output = outp
49+
}
50+
}
51+
52+
private class MethodModels extends TaintTracking::FunctionModel, Method {
53+
FunctionInput inp;
54+
FunctionOutput outp;
55+
56+
MethodModels() {
57+
// signature: func (*Decoder).Buffered() io.Reader
58+
this.hasQualifiedName("encoding/json", "Decoder", "Buffered") and
59+
(inp.isReceiver() and outp.isResult())
60+
or
61+
// signature: func (*Decoder).Decode(v interface{}) error
62+
this.hasQualifiedName("encoding/json", "Decoder", "Decode") and
63+
(inp.isReceiver() and outp.isParameter(0))
64+
or
65+
// signature: func (*Decoder).Token() (Token, error)
66+
this.hasQualifiedName("encoding/json", "Decoder", "Token") and
67+
(inp.isReceiver() and outp.isResult(0))
68+
or
69+
// signature: func (*Encoder).Encode(v interface{}) error
70+
this.hasQualifiedName("encoding/json", "Encoder", "Encode") and
71+
(inp.isParameter(0) and outp.isReceiver())
72+
or
73+
// signature: func (*Encoder).SetIndent(prefix string, indent string)
74+
this.hasQualifiedName("encoding/json", "Encoder", "SetIndent") and
75+
(inp.isParameter(_) and outp.isReceiver())
76+
or
77+
// signature: func (RawMessage).MarshalJSON() ([]byte, error)
78+
this.hasQualifiedName("encoding/json", "RawMessage", "MarshalJSON") and
79+
(inp.isReceiver() and outp.isResult(0))
80+
or
81+
// signature: func (*RawMessage).UnmarshalJSON(data []byte) error
82+
this.hasQualifiedName("encoding/json", "RawMessage", "UnmarshalJSON") and
83+
(inp.isParameter(0) and outp.isReceiver())
84+
or
85+
// signature: func (Marshaler).MarshalJSON() ([]byte, error)
86+
this.implements("encoding/json", "Marshaler", "MarshalJSON") and
87+
(inp.isReceiver() and outp.isResult(0))
88+
or
89+
// signature: func (Unmarshaler).UnmarshalJSON([]byte) error
90+
this.implements("encoding/json", "Unmarshaler", "UnmarshalJSON") and
91+
(inp.isParameter(0) and outp.isReceiver())
92+
}
93+
94+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
95+
input = inp and output = outp
96+
}
97+
}
98+
}

ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/EncodingJson.go

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

0 commit comments

Comments
 (0)