Skip to content

Commit ffe2e39

Browse files
committed
fix tests, add support for Response.BodyWriter() Thanks to @owen-mc
1 parent accc09f commit ffe2e39

File tree

3 files changed

+36
-25
lines changed

3 files changed

+36
-25
lines changed

go/ql/lib/semmle/go/frameworks/Fasthttp.qll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,24 @@ module Fasthttp {
236236
]) and
237237
this = m.getACall().getArgument(0)
238238
)
239+
or
240+
exists(Method write, DataFlow::CallNode writeCall |
241+
write.hasQualifiedName("io", "Writer", "Write") and
242+
writeCall = write.getACall() and
243+
ResponseBodyWriterFlow::flowsTo(writeCall.getReceiver()) and
244+
this = writeCall.getArgument(0)
245+
)
239246
}
240247
}
248+
249+
private predicate responseBodyWriterResult(DataFlow::Node src) {
250+
exists(Method responseBodyWriter |
251+
responseBodyWriter.hasQualifiedName(packagePath(), "Response", "BodyWriter") and
252+
src = responseBodyWriter.getACall().getResult(0)
253+
)
254+
}
255+
256+
private module ResponseBodyWriterFlow = DataFlow::SimpleGlobal<responseBodyWriterResult/1>;
241257
}
242258

243259
/**
Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,2 @@
11
testFailures
2-
| fasthttp.go:165:41:165:86 | comment | Missing result:UntrustedFlowSource="call to BodyInflate" |
3-
| fasthttp.go:166:41:166:87 | comment | Missing result:UntrustedFlowSource="call to BodyUnbrotli" |
4-
| fasthttp.go:168:41:168:91 | comment | Missing result:UntrustedFlowSource="call to BodyUncompressed" |
52
failures

go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/fasthttp.go

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package main
44

55
import (
66
"bufio"
7+
"fmt"
78
"net"
89
"time"
910

@@ -40,12 +41,12 @@ func fasthttpClient() {
4041
uri4 := fasthttp.AcquireURI()
4142
uri4.UpdateBytes(source().([]byte))
4243
sink(uri4) // $ hasTaintFlow="uri4"
43-
uri5 := fasthttp.AcquireURI()
44-
uri5.Parse(source().([]byte), nil)
45-
sink(uri5) // $ hasTaintFlow="uri5"
46-
uri6 := fasthttp.AcquireURI()
47-
uri6.Parse(nil, source().([]byte))
48-
sink(uri6) // $ hasTaintFlow="uri6"
44+
uri5 := fasthttp.AcquireURI()
45+
uri5.Parse(source().([]byte), nil)
46+
sink(uri5) // $ hasTaintFlow="uri5"
47+
uri6 := fasthttp.AcquireURI()
48+
uri6.Parse(nil, source().([]byte))
49+
sink(uri6) // $ hasTaintFlow="uri6"
4950

5051
resByte := make([]byte, 1000)
5152
userInput = "http://127.0.0.1:8909"
@@ -144,8 +145,6 @@ func fasthttpServer() {
144145
requestCtx.URI().QueryArgs().QueryString() // $ UntrustedFlowSource="call to QueryString"
145146
requestCtx.URI().QueryArgs().String() // $ UntrustedFlowSource="call to String"
146147
requestCtx.String() // $ UntrustedFlowSource="call to String"
147-
// not sure what is the best way to write query for following
148-
//requestCtx.URI().QueryArgs().VisitAll(type func(,))
149148

150149
requestCtx.Path() // $ UntrustedFlowSource="call to Path"
151150
// multipart.Form is already implemented
@@ -158,29 +157,28 @@ func fasthttpServer() {
158157
requestCtx.UserAgent() // $ UntrustedFlowSource="call to UserAgent"
159158
requestCtx.Host() // $ UntrustedFlowSource="call to Host"
160159

161-
requestCtx.Request.Host() // $ UntrustedFlowSource="call to Host"
162-
requestCtx.Request.Body() // $ UntrustedFlowSource="call to Body"
163-
requestCtx.Request.RequestURI() // $ UntrustedFlowSource="call to RequestURI"
164-
requestCtx.Request.BodyGunzip() // $ UntrustedFlowSource="call to BodyGunzip"
165-
requestCtx.Request.BodyInflate() // $ UntrustedFlowSource="call to BodyInflate"
166-
requestCtx.Request.BodyUnbrotli() // $ UntrustedFlowSource="call to BodyUnbrotli"
167-
requestCtx.Request.BodyStream() // $ UntrustedFlowSource="call to BodyStream"
168-
requestCtx.Request.BodyUncompressed() // $ UntrustedFlowSource="call to BodyUncompressed"
160+
requestCtx.Request.Host() // $ UntrustedFlowSource="call to Host"
161+
requestCtx.Request.Body() // $ UntrustedFlowSource="call to Body"
162+
requestCtx.Request.RequestURI() // $ UntrustedFlowSource="call to RequestURI"
163+
body1, _ := requestCtx.Request.BodyGunzip() //$ UntrustedFlowSource="... := ...[0]"
164+
body2, _ := requestCtx.Request.BodyInflate() //$ UntrustedFlowSource="... := ...[0]"
165+
body3, _ := requestCtx.Request.BodyUnbrotli() //$ UntrustedFlowSource="... := ...[0]"
166+
body4, _ := requestCtx.Request.BodyUncompressed() //$ UntrustedFlowSource="... := ...[0]"
167+
requestCtx.Request.BodyStream() // $ UntrustedFlowSource="call to BodyStream"
169168
requestCtx.Request.ReadBody(dstReader, 100, 1000)
170169
requestCtx.Request.ReadLimitBody(dstReader, 100)
171170
requestCtx.Request.ContinueReadBodyStream(dstReader, 100, true)
172171
requestCtx.Request.ContinueReadBody(dstReader, 100)
173-
// not sure what is the best way to write query for following
174-
//requestCtx.Request.Header.VisitAllCookie()
172+
fmt.Println(body1, body2, body3, body4)
175173

176174
// Response methods
177175
// Xss Sinks Related method
178176
userInput := "user Controlled input"
179177
userInputByte := []byte("user Controlled input")
180-
requestCtx.Response.AppendBody(userInputByte) // $ XssSink=userInputByte
181-
requestCtx.Response.AppendBodyString(userInput) // $ XssSink=userInput
182-
rspWriter := requestCtx.Response.BodyWriter() // IDK how to handle this that returns a `io.Writer`
183-
rspWriter.Write(userInputByte)
178+
requestCtx.Response.AppendBody(userInputByte) // $ XssSink=userInputByte
179+
requestCtx.Response.AppendBodyString(userInput) // $ XssSink=userInput
180+
rspWriter := requestCtx.Response.BodyWriter() // IDK how to handle this that returns a `io.Writer`
181+
rspWriter.Write(userInputByte) // $ XssSink=userInputByte
184182
requestCtx.Response.SetBody(userInputByte) // $ XssSink=userInputByte
185183
requestCtx.Response.SetBodyString(userInput) // $ XssSink=userInput
186184
requestCtx.Response.SetBodyRaw(userInputByte) // $ XssSink=userInputByte

0 commit comments

Comments
 (0)