diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/AdditionalTaintSteps.ql b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/AdditionalTaintSteps.ql index f9013a173f7..d71fdc8d706 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/AdditionalTaintSteps.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/AdditionalTaintSteps.ql @@ -2,25 +2,43 @@ import go import TestUtilities.InlineExpectationsTest module FasthttpTest implements TestSig { - string getARelevantTag() { result = ["URI", "req"] } + string getARelevantTag() { result = ["UriSucc","UriPred", "ReqSucc", "ReqPred"] } predicate hasActualResult(Location location, string element, string tag, string value) { - exists(Fasthttp::Request::RequestAdditionalStep q, DataFlow::Node succ | - q.hasTaintStep(_, succ) + exists(Fasthttp::Request::RequestAdditionalStep q, DataFlow::Node succ, DataFlow::Node pred | + q.hasTaintStep(pred, succ) | - succ.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), - location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and - element = succ.toString() and - value = succ.toString() and - tag = "req" + ( + pred.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = pred.toString() and + value = pred.toString() and + tag = "ReqPred" + or + succ.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = succ.toString() and + value = succ.toString() and + tag = "ReqSucc" + ) ) or - exists(Fasthttp::URI::UriAdditionalStep q, DataFlow::Node succ | q.hasTaintStep(_, succ) | - succ.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), - location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and - element = succ.toString() and - value = succ.toString() and - tag = "URI" + exists(Fasthttp::URI::UriAdditionalStep q, DataFlow::Node succ, DataFlow::Node pred | + q.hasTaintStep(pred, succ) + | + ( + pred.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = pred.toString() and + value = pred.toString() and + tag = "UriPred" + or + succ.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = succ.toString() and + value = succ.toString() and + tag = "UriSucc" + ) ) } } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/SSRF.expected b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/SSRF.expected deleted file mode 100644 index 42cee99d283..00000000000 --- a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/SSRF.expected +++ /dev/null @@ -1,38 +0,0 @@ -| fasthttp.go:14:42:14:57 | "127.0.0.1:8909" | -| fasthttp.go:15:32:15:46 | "google.com:80" | -| fasthttp.go:16:39:16:53 | "google.com:80" | -| fasthttp.go:17:48:17:62 | "google.com:80" | -| fasthttp.go:28:24:28:46 | "http://127.0.0.1:8909" | -| fasthttp.go:29:32:29:54 | "http://127.0.0.1:8909" | -| fasthttp.go:30:31:30:53 | "http://127.0.0.1:8909" | -| fasthttp.go:31:25:31:47 | "http://127.0.0.1:8909" | -| fasthttp.go:33:14:33:16 | req | -| fasthttp.go:34:23:34:25 | req | -| fasthttp.go:35:22:35:24 | req | -| fasthttp.go:36:21:36:23 | req | -| fasthttp.go:55:26:55:48 | "http://127.0.0.1:8909" | -| fasthttp.go:56:34:56:56 | "http://127.0.0.1:8909" | -| fasthttp.go:57:33:57:55 | "http://127.0.0.1:8909" | -| fasthttp.go:58:27:58:49 | "http://127.0.0.1:8909" | -| fasthttp.go:59:16:59:18 | req | -| fasthttp.go:60:24:60:26 | req | -| fasthttp.go:61:25:61:27 | req | -| fasthttp.go:62:23:62:25 | req | -| fasthttp.go:66:14:66:16 | req | -| fasthttp.go:67:22:67:24 | req | -| fasthttp.go:68:21:68:23 | req | -| fasthttp.go:71:13:71:19 | resByte | -| fasthttp.go:72:21:72:27 | resByte | -| fasthttp.go:73:20:73:26 | resByte | -| fasthttp.go:74:14:74:20 | resByte | -| fasthttp.go:75:12:75:14 | req | -| fasthttp.go:76:20:76:22 | req | -| fasthttp.go:77:21:77:23 | req | -| fasthttp.go:78:19:78:21 | req | -| fasthttp.go:81:20:81:22 | req | -| fasthttp.go:82:28:82:30 | req | -| fasthttp.go:83:27:83:29 | req | -| fasthttp.go:86:17:86:32 | "127.0.0.1:8909" | -| fasthttp.go:87:24:87:39 | "127.0.0.1:8909" | -| fasthttp.go:88:26:88:41 | "127.0.0.1:8909" | -| fasthttp.go:89:33:89:48 | "127.0.0.1:8909" | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/fasthttp.go b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/fasthttp.go index 9405707cc1e..4cb935d3ed9 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/fasthttp.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/fasthttp.go @@ -10,6 +10,8 @@ import ( ) func fasthttpClient() { + userInput := "user Controlled input" + userInputByte := []byte("user Controlled input") // #SSRF response, _ := fasthttp.DialDualStack("127.0.0.1:8909") response, _ = fasthttp.Dial("google.com:80") @@ -18,31 +20,33 @@ func fasthttpClient() { resByte := make([]byte, 1000) _, _ = response.Read(resByte) - // #SSRF res := &fasthttp.Response{} req := &fasthttp.Request{} + req.SetHost(userInput) // $ ReqSucc=req ReqPred=userInput + req.SetHostBytes(userInputByte) // $ ReqSucc=req ReqPred=userInputByte + req.SetRequestURI(userInput) // $ ReqSucc=req ReqPred=userInput + req.SetRequestURIBytes(userInputByte) // $ ReqSucc=req ReqPred=userInputByte + uri := fasthttp.AcquireURI() + userInput = "UserControlled.com:80" + userInputByte = []byte("UserControlled.com:80") + uri.SetHost(userInput) // $ UriPred=userInput UriSucc=uri + uri.SetHostBytes(userInputByte) // $ UriPred=userInputByte UriSucc=uri + userInput = "http://UserControlled.com" + userInputByte = []byte("http://UserControlled.com") + uri.Update(userInput) // $ UriPred=userInput UriSucc=uri + uri.UpdateBytes(userInputByte) // $ UriPred=userInputByte UriSucc=uri + uri.Parse(userInputByte, userInputByte) // $ UriPred=userInputByte UriPred=userInputByte UriSucc=uri + req.SetURI(uri) // $ ReqSucc=req ReqPred=uri UriSucc=uri + fasthttp.Get(resByte, "http://127.0.0.1:8909") // $ SSRF="http://127.0.0.1:8909" fasthttp.GetDeadline(resByte, "http://127.0.0.1:8909", time.Time{}) // $ SSRF="http://127.0.0.1:8909" fasthttp.GetTimeout(resByte, "http://127.0.0.1:8909", 5) // $ SSRF="http://127.0.0.1:8909" fasthttp.Post(resByte, "http://127.0.0.1:8909", nil) // $ SSRF="http://127.0.0.1:8909" - fasthttp.Do(req, res) // $ req=req - fasthttp.DoRedirects(req, res, 2) // $ req=req - fasthttp.DoDeadline(req, res, time.Time{}) // $ req=req - fasthttp.DoTimeout(req, res, 5) // $ req=req - - // additional steps - uri.SetHost("UserControlled.com:80") // $ URI=uri - uri.SetHostBytes([]byte("UserControlled.com:80")) // $ URI=uri - uri.Update("http://httpbin.org/ip") // $ URI=uri - uri.UpdateBytes([]byte("http://httpbin.org/ip")) // $ URI=uri - uri.Parse(nil, []byte("http://httpbin.org/ip")) // $ URI=uri - - req.SetHost("UserControlled.com:80") // $ req=req - req.SetHostBytes([]byte("UserControlled.com:80")) // $ req=req - req.SetRequestURI("https://UserControlled.com") // $ req=req - req.SetRequestURIBytes([]byte("https://UserControlled.com")) // $ req=req - req.SetURI(uri) // $ req=req URI=uri + fasthttp.Do(req, res) // $ ReqSucc=req + fasthttp.DoRedirects(req, res, 2) // $ ReqSucc=req + fasthttp.DoDeadline(req, res, time.Time{}) // $ ReqSucc=req + fasthttp.DoTimeout(req, res, 5) // $ ReqSucc=req hostClient := &fasthttp.HostClient{ Addr: "localhost:8080", @@ -51,31 +55,31 @@ func fasthttpClient() { hostClient.GetDeadline(resByte, "http://127.0.0.1:8909", time.Time{}) // $ SSRF="http://127.0.0.1:8909" hostClient.GetTimeout(resByte, "http://127.0.0.1:8909", 5) // $ SSRF="http://127.0.0.1:8909" hostClient.Post(resByte, "http://127.0.0.1:8909", nil) // $ SSRF="http://127.0.0.1:8909" - hostClient.Do(req, res) // $ req=req - hostClient.DoDeadline(req, res, time.Time{}) // $ req=req - hostClient.DoRedirects(req, res, 2) // $ req=req - hostClient.DoTimeout(req, res, 5) // $ req=req + hostClient.Do(req, res) // $ ReqSucc=req + hostClient.DoDeadline(req, res, time.Time{}) // $ ReqSucc=req + hostClient.DoRedirects(req, res, 2) // $ ReqSucc=req + hostClient.DoTimeout(req, res, 5) // $ ReqSucc=req var lbclient fasthttp.LBClient lbclient.Clients = append(lbclient.Clients, hostClient) - lbclient.Do(req, res) // $ req=req - lbclient.DoDeadline(req, res, time.Time{}) // $ req=req - lbclient.DoTimeout(req, res, 5) // $ req=req + lbclient.Do(req, res) // $ ReqSucc=req + lbclient.DoDeadline(req, res, time.Time{}) // $ ReqSucc=req + lbclient.DoTimeout(req, res, 5) // $ ReqSucc=req client := fasthttp.Client{} client.Get(resByte, "http://127.0.0.1:8909") // $ SSRF="http://127.0.0.1:8909" client.GetDeadline(resByte, "http://127.0.0.1:8909", time.Time{}) // $ SSRF="http://127.0.0.1:8909" client.GetTimeout(resByte, "http://127.0.0.1:8909", 5) // $ SSRF="http://127.0.0.1:8909" client.Post(resByte, "http://127.0.0.1:8909", nil) // $ SSRF="http://127.0.0.1:8909" - client.Do(req, res) // $ req=req SSRF=req - client.DoDeadline(req, res, time.Time{}) // $ req=req SSRF=req - client.DoRedirects(req, res, 2) // $ req=req SSRF=req - client.DoTimeout(req, res, 5) // $ req=req SSRF=req + client.Do(req, res) // $ ReqSucc=req SSRF=req + client.DoDeadline(req, res, time.Time{}) // $ ReqSucc=req SSRF=req + client.DoRedirects(req, res, 2) // $ ReqSucc=req SSRF=req + client.DoTimeout(req, res, 5) // $ ReqSucc=req SSRF=req pipelineClient := fasthttp.PipelineClient{} - pipelineClient.Do(req, res) // $ req=req SSRF=req - pipelineClient.DoDeadline(req, res, time.Time{}) // $ req=req SSRF=req - pipelineClient.DoTimeout(req, res, 5) // $ req=req SSRF=req + pipelineClient.Do(req, res) // $ ReqSucc=req SSRF=req + pipelineClient.DoDeadline(req, res, time.Time{}) // $ ReqSucc=req SSRF=req + pipelineClient.DoTimeout(req, res, 5) // $ ReqSucc=req SSRF=req tcpDialer := fasthttp.TCPDialer{} tcpDialer.Dial("127.0.0.1:8909") // $ SSRF="127.0.0.1:8909"