From 14e758a6ea3acf370f00c41d6c47ab93fa23f754 Mon Sep 17 00:00:00 2001 From: Sauyon Lee Date: Thu, 27 Feb 2020 00:22:37 -0800 Subject: [PATCH] HTTP: Add model for Header.Values() --- ql/src/semmle/go/frameworks/HTTP.qll | 4 ++++ .../semmle/go/frameworks/HTTP/Header.expected | 2 +- .../HTTP/UntrustedFlowSources.expected | 6 ++++++ .../semmle/go/frameworks/HTTP/main.go | 2 +- .../semmle/go/frameworks/HTTP/server.go | 19 +++++++++++++++++++ 5 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 ql/test/library-tests/semmle/go/frameworks/HTTP/server.go diff --git a/ql/src/semmle/go/frameworks/HTTP.qll b/ql/src/semmle/go/frameworks/HTTP.qll index 84dd956f09a..d16e9df2a41 100644 --- a/ql/src/semmle/go/frameworks/HTTP.qll +++ b/ql/src/semmle/go/frameworks/HTTP.qll @@ -19,6 +19,10 @@ private module StdlibHttp { HeaderGetCall() { this.getTarget().hasQualifiedName("net/http", "Header", "Get") } } + private class HeaderValuesCall extends UntrustedFlowSource::Range, DataFlow::MethodCallNode { + HeaderValuesCall() { this.getTarget().hasQualifiedName("net/http", "Header", "Values") } + } + private class StdlibResponseWriter extends HTTP::ResponseWriter::Range { StdlibResponseWriter() { this.getType().implements("net/http", "ResponseWriter") } diff --git a/ql/test/library-tests/semmle/go/frameworks/HTTP/Header.expected b/ql/test/library-tests/semmle/go/frameworks/HTTP/Header.expected index 62a0488cc48..ea04e232bcc 100644 --- a/ql/test/library-tests/semmle/go/frameworks/HTTP/Header.expected +++ b/ql/test/library-tests/semmle/go/frameworks/HTTP/Header.expected @@ -2,7 +2,7 @@ | main.go:31:2:31:51 | call to Set | "Authorization" | "Basic example:example" | authorization | Basic example:example | | main.go:32:2:32:26 | call to Add | "Age" | "342232" | age | 342232 | | main.go:34:2:34:55 | call to Add | server | call to Sprintf | n/a | n/a | -| main.go:35:2:35:36 | call to Set | LOC_HEADER | ...+... | n/a | n/a | +| main.go:35:2:35:45 | call to Set | LOC_HEADER | ...+... | n/a | n/a | | main.go:36:2:36:5 | head | "Unknown-Header" | composite literal | n/a | n/a | | main.go:48:2:48:43 | call to Add | "Not-A-Response" | "Header" | not-a-response | Header | | main.go:49:2:49:42 | call to Set | "Accept" | "nota/response" | accept | nota/response | diff --git a/ql/test/library-tests/semmle/go/frameworks/HTTP/UntrustedFlowSources.expected b/ql/test/library-tests/semmle/go/frameworks/HTTP/UntrustedFlowSources.expected index 0ddcc26e37e..29b6ab54574 100644 --- a/ql/test/library-tests/semmle/go/frameworks/HTTP/UntrustedFlowSources.expected +++ b/ql/test/library-tests/semmle/go/frameworks/HTTP/UntrustedFlowSources.expected @@ -9,3 +9,9 @@ | main.go:48:2:48:11 | selection of Header | | main.go:49:2:49:11 | selection of Header | | main.go:50:2:50:11 | selection of Header | +| server.go:8:6:8:13 | selection of Header | +| server.go:9:6:9:13 | selection of Header | +| server.go:9:6:9:38 | call to Values | +| server.go:10:6:10:13 | selection of Header | +| server.go:10:6:10:35 | call to Get | +| server.go:13:6:13:11 | selection of Body | diff --git a/ql/test/library-tests/semmle/go/frameworks/HTTP/main.go b/ql/test/library-tests/semmle/go/frameworks/HTTP/main.go index 6a55524d0d7..cb8e8a85b43 100644 --- a/ql/test/library-tests/semmle/go/frameworks/HTTP/main.go +++ b/ql/test/library-tests/semmle/go/frameworks/HTTP/main.go @@ -32,7 +32,7 @@ func handler(w http.ResponseWriter, r *http.Request) { head.Add("Age", "342232") server := "Server" head.Add(server, fmt.Sprintf("Server: %s", "example")) - head.Set(LOC_HEADER, rfs4+"/redir") + head.Set(LOC_HEADER, rfs4.String()+"/redir") head["Unknown-Header"] = []string{"Some value!"} w.Write([]byte("Some more body text\n")) diff --git a/ql/test/library-tests/semmle/go/frameworks/HTTP/server.go b/ql/test/library-tests/semmle/go/frameworks/HTTP/server.go new file mode 100644 index 00000000000..87110984755 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/HTTP/server.go @@ -0,0 +1,19 @@ +package main + +import ( + "net/http" +) + +func Handler(r *http.Request) { + use(r.Header) + use(r.Header.Values("X-Forwarded-By")) + use(r.Header.Get("Authentication")) + + buf := make([]byte, 100) + use(r.Body.Read(buf)) + body, err := r.GetBody() + if err != nil { + return + } + use(body.Read(buf)) +}