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

Commit e66fcef

Browse files
committed
Add taint-tracking for net/http package
1 parent fa04d5a commit e66fcef

3 files changed

Lines changed: 404 additions & 0 deletions

File tree

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import semmle.go.frameworks.stdlib.EncodingXml
3030
import semmle.go.frameworks.stdlib.Html
3131
import semmle.go.frameworks.stdlib.HtmlTemplate
3232
import semmle.go.frameworks.stdlib.Net
33+
import semmle.go.frameworks.stdlib.NetHttp
3334
import semmle.go.frameworks.stdlib.Path
3435
import semmle.go.frameworks.stdlib.PathFilepath
3536
import semmle.go.frameworks.stdlib.Reflect
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `net/http` package.
3+
*/
4+
5+
import go
6+
7+
/** Provides models of commonly used functions in the `net/http` package. */
8+
module NetHttp {
9+
private class FunctionModels extends TaintTracking::FunctionModel {
10+
FunctionInput inp;
11+
FunctionOutput outp;
12+
13+
FunctionModels() {
14+
// signature: func CanonicalHeaderKey(s string) string
15+
hasQualifiedName("net/http", "CanonicalHeaderKey") and
16+
(inp.isParameter(0) and outp.isResult())
17+
or
18+
// signature: func Error(w ResponseWriter, error string, code int)
19+
hasQualifiedName("net/http", "Error") and
20+
(inp.isParameter(1) and outp.isParameter(0))
21+
or
22+
// signature: func MaxBytesReader(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser
23+
hasQualifiedName("net/http", "MaxBytesReader") and
24+
(inp.isParameter(1) and outp.isResult())
25+
or
26+
// signature: func ReadRequest(b *bufio.Reader) (*Request, error)
27+
hasQualifiedName("net/http", "ReadRequest") and
28+
(inp.isParameter(0) and outp.isResult(0))
29+
or
30+
// signature: func ReadResponse(r *bufio.Reader, req *Request) (*Response, error)
31+
hasQualifiedName("net/http", "ReadResponse") and
32+
(inp.isParameter(0) and outp.isResult(0))
33+
or
34+
// signature: func SetCookie(w ResponseWriter, cookie *Cookie)
35+
hasQualifiedName("net/http", "SetCookie") and
36+
(inp.isParameter(1) and outp.isParameter(0))
37+
}
38+
39+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
40+
input = inp and output = outp
41+
}
42+
}
43+
44+
private class MethodModels extends TaintTracking::FunctionModel, Method {
45+
FunctionInput inp;
46+
FunctionOutput outp;
47+
48+
MethodModels() {
49+
// signature: func (Header).Add(key string, value string)
50+
this.hasQualifiedName("net/http", "Header", "Add") and
51+
(inp.isParameter(_) and outp.isReceiver())
52+
or
53+
// signature: func (Header).Clone() Header
54+
this.hasQualifiedName("net/http", "Header", "Clone") and
55+
(inp.isReceiver() and outp.isResult())
56+
or
57+
// signature: func (Header).Get(key string) string
58+
this.hasQualifiedName("net/http", "Header", "Get") and
59+
(inp.isReceiver() and outp.isResult())
60+
or
61+
// signature: func (Header).Set(key string, value string)
62+
this.hasQualifiedName("net/http", "Header", "Set") and
63+
(inp.isParameter(_) and outp.isReceiver())
64+
or
65+
// signature: func (Header).Values(key string) []string
66+
this.hasQualifiedName("net/http", "Header", "Values") and
67+
(inp.isReceiver() and outp.isResult())
68+
or
69+
// signature: func (Header).Write(w io.Writer) error
70+
this.hasQualifiedName("net/http", "Header", "Write") and
71+
(inp.isReceiver() and outp.isParameter(0))
72+
or
73+
// signature: func (Header).WriteSubset(w io.Writer, exclude map[string]bool) error
74+
this.hasQualifiedName("net/http", "Header", "WriteSubset") and
75+
(inp.isReceiver() and outp.isParameter(0))
76+
or
77+
// signature: func (*Request).AddCookie(c *Cookie)
78+
this.hasQualifiedName("net/http", "Request", "AddCookie") and
79+
(inp.isParameter(0) and outp.isReceiver())
80+
or
81+
// signature: func (*Request).Clone(ctx context.Context) *Request
82+
this.hasQualifiedName("net/http", "Request", "Clone") and
83+
(inp.isReceiver() and outp.isResult())
84+
or
85+
// signature: func (*Request).Write(w io.Writer) error
86+
this.hasQualifiedName("net/http", "Request", "Write") and
87+
(inp.isReceiver() and outp.isParameter(0))
88+
or
89+
// signature: func (*Request).WriteProxy(w io.Writer) error
90+
this.hasQualifiedName("net/http", "Request", "WriteProxy") and
91+
(inp.isReceiver() and outp.isParameter(0))
92+
or
93+
// signature: func (*Response).Write(w io.Writer) error
94+
this.hasQualifiedName("net/http", "Response", "Write") and
95+
(inp.isReceiver() and outp.isParameter(0))
96+
or
97+
// signature: func (*Transport).Clone() *Transport
98+
this.hasQualifiedName("net/http", "Transport", "Clone") and
99+
(inp.isReceiver() and outp.isResult())
100+
or
101+
// signature: func (Hijacker).Hijack() (net.Conn, *bufio.ReadWriter, error)
102+
this.implements("net/http", "Hijacker", "Hijack") and
103+
(inp.isReceiver() and outp.isResult([0, 1]))
104+
or
105+
// signature: func (ResponseWriter).Write([]byte) (int, error)
106+
this.implements("net/http", "ResponseWriter", "Write") and
107+
(inp.isParameter(0) and outp.isReceiver())
108+
}
109+
110+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
111+
input = inp and output = outp
112+
}
113+
}
114+
}

0 commit comments

Comments
 (0)