diff --git a/ql/src/go.qll b/ql/src/go.qll index 524717b7544..b234154bc8e 100644 --- a/ql/src/go.qll +++ b/ql/src/go.qll @@ -34,5 +34,6 @@ import semmle.go.frameworks.SQL import semmle.go.frameworks.XPath import semmle.go.frameworks.Stdlib import semmle.go.frameworks.Testing +import semmle.go.frameworks.Websocket import semmle.go.security.FlowSources import semmle.go.Util diff --git a/ql/src/semmle/go/Packages.qll b/ql/src/semmle/go/Packages.qll index 6b24a3cc6ab..2187bcf47c2 100644 --- a/ql/src/semmle/go/Packages.qll +++ b/ql/src/semmle/go/Packages.qll @@ -24,3 +24,12 @@ class Package extends @package { /** Gets a textual representation of this element. */ string toString() { result = "package " + getPath() } } + +/** + * Gets the Go import string that may identify a package in module `mod` with the given path, + * possibly modulo semantic import versioning. + */ +bindingset[result, mod, path] +string package(string mod, string path) { + result.regexpMatch("\\Q" + mod + "\\E([/.]v[^/]+)?/\\Q" + path + "\\E") +} diff --git a/ql/src/semmle/go/dataflow/BarrierGuardUtil.qll b/ql/src/semmle/go/dataflow/BarrierGuardUtil.qll new file mode 100644 index 00000000000..0dfbb5dc046 --- /dev/null +++ b/ql/src/semmle/go/dataflow/BarrierGuardUtil.qll @@ -0,0 +1,69 @@ +/** + * Contains implementations of some commonly used barrier + * guards for sanitizing untrusted URLs. + */ + +import go + +/** + * A call to a function called `isLocalUrl`, `isValidRedirect`, or similar, which is + * considered a barrier guard for sanitizing untrusted URLs. + */ +class RedirectCheckBarrierGuard extends DataFlow::BarrierGuard, DataFlow::CallNode { + RedirectCheckBarrierGuard() { + this.getCalleeName().regexpMatch("(?i)(is_?)?(local_?url|valid_?redir(ect)?)") + } + + override predicate checks(Expr e, boolean outcome) { + // `isLocalUrl(e)` is a barrier for `e` if it evaluates to `true` + getAnArgument().asExpr() = e and + outcome = true + } +} + +/** + * An equality check comparing a data-flow node against a constant string, considered as + * a barrier guard for sanitizing untrusted URLs. + * + * Additionally, a check comparing `url.Hostname()` against a constant string is also + * considered a barrier guard for `url`. + */ +class UrlCheck extends DataFlow::BarrierGuard, DataFlow::EqualityTestNode { + DataFlow::Node url; + + UrlCheck() { + exists(this.getAnOperand().getStringValue()) and + ( + url = this.getAnOperand() + or + exists(DataFlow::MethodCallNode mc | mc = this.getAnOperand() | + mc.getTarget().getName() = "Hostname" and + url = mc.getReceiver() + ) + ) + } + + override predicate checks(Expr e, boolean outcome) { + e = url.asExpr() and outcome = this.getPolarity() + } +} + +/** + * A call to a regexp match function, considered as a barrier guard for sanitizing untrusted URLs. + * + * This is overapproximate: we do not attempt to reason about the correctness of the regexp. + */ +class RegexpCheck extends DataFlow::BarrierGuard { + RegexpMatchFunction matchfn; + DataFlow::CallNode call; + + RegexpCheck() { + matchfn.getACall() = call and + this = matchfn.getResult().getNode(call).getASuccessor*() + } + + override predicate checks(Expr e, boolean branch) { + e = matchfn.getValue().getNode(call).asExpr() and + (branch = false or branch = true) + } +} diff --git a/ql/src/semmle/go/frameworks/Websocket.qll b/ql/src/semmle/go/frameworks/Websocket.qll new file mode 100644 index 00000000000..c16555da39f --- /dev/null +++ b/ql/src/semmle/go/frameworks/Websocket.qll @@ -0,0 +1,134 @@ +/** Provides classes for working with WebSocket-related APIs. */ + +import go + +/** + * A data-flow node that establishes a new WebSocket connection. + * + * Extend this class to refine existing API models. If you want to model new APIs, + * extend `WebSocketRequestCall::Range` instead. + */ +class WebSocketRequestCall extends DataFlow::CallNode { + WebSocketRequestCall::Range self; + + WebSocketRequestCall() { this = self } + + /** Gets the URL of the request. */ + DataFlow::Node getRequestUrl() { result = self.getRequestUrl() } +} + +/** Provides classes for working with WebSocket request functions. */ +module WebSocketRequestCall { + /** + * A data-flow node that establishes a new WebSocket connection. + * + * Extend this class to model new APIs. If you want to refine existing + * API models, extend `WebSocketRequestCall` instead. + */ + abstract class Range extends DataFlow::CallNode { + /** Gets the URL of the request. */ + abstract DataFlow::Node getRequestUrl(); + } + + /** + * A WebSocket request expression string used in an API function of the + * `golang.org/x/net/websocket` package. + */ + private class GolangXNetDialFunc extends Range { + GolangXNetDialFunc() { + // func Dial(url_, protocol, origin string) (ws *Conn, err error) + this.getTarget().hasQualifiedName(package("golang.org/x/net", "websocket"), "Dial") + } + + override DataFlow::Node getRequestUrl() { result = this.getArgument(0) } + } + + /** + * A WebSocket DialConfig expression string used in an API function + * of the `golang.org/x/net/websocket` package. + */ + private class GolangXNetDialConfigFunc extends Range { + GolangXNetDialConfigFunc() { + // func DialConfig(config *Config) (ws *Conn, err error) + this.getTarget().hasQualifiedName(package("golang.org/x/net", "websocket"), "DialConfig") + } + + override DataFlow::Node getRequestUrl() { + exists(DataFlow::CallNode cn | + // func NewConfig(server, origin string) (config *Config, err error) + cn.getTarget().hasQualifiedName(package("golang.org/x/net", "websocket"), "NewConfig") and + this.getArgument(0) = cn.getResult(0).getASuccessor*() and + result = cn.getArgument(0) + ) + } + } + + /** + * A WebSocket request expression string used in an API function + * of the `github.com/gorilla/websocket` package. + */ + private class GorillaWebsocketDialFunc extends Range { + DataFlow::Node url; + + GorillaWebsocketDialFunc() { + // func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) + // func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) + exists(string name, Method f | + f = this.getTarget() and + f.hasQualifiedName(package("github.com/gorilla", "websocket"), "Dialer", name) + | + name = "Dial" and this.getArgument(0) = url + or + name = "DialContext" and this.getArgument(1) = url + ) + } + + override DataFlow::Node getRequestUrl() { result = url } + } + + /** + * A WebSocket request expression string used in an API function + * of the `github.com/gobwas/ws` package. + */ + private class GobwasWsDialFunc extends Range { + GobwasWsDialFunc() { + // func (d Dialer) Dial(ctx context.Context, urlstr string) (conn net.Conn, br *bufio.Reader, hs Handshake, err error) + exists(Method m | + m.hasQualifiedName(package("github.com/gobwas", "ws"), "Dialer", "Dial") and + m = this.getTarget() + ) + or + // func Dial(ctx context.Context, urlstr string) (net.Conn, *bufio.Reader, Handshake, error) + this.getTarget().hasQualifiedName(package("github.com/gobwas", "ws"), "Dial") + } + + override DataFlow::Node getRequestUrl() { result = this.getArgument(1) } + } + + /** + * A WebSocket request expression string used in an API function + * of the `nhooyr.io/websocket` package. + */ + private class NhooyrWebsocketDialFunc extends Range { + NhooyrWebsocketDialFunc() { + // func Dial(ctx context.Context, u string, opts *DialOptions) (*Conn, *http.Response, error) + this.getTarget().hasQualifiedName(package("nhooyr.io", "websocket"), "Dial") + } + + override DataFlow::Node getRequestUrl() { result = this.getArgument(1) } + } + + /** + * A WebSocket request expression string used in an API function + * of the `github.com/sacOO7/gowebsocket` package. + */ + private class SacOO7DialFunc extends Range { + SacOO7DialFunc() { + // func BuildProxy(Url string) func(*http.Request) (*url.URL, error) + // func New(url string) Socket + this.getTarget().hasQualifiedName("github.com/sacOO7/gowebsocket", ["New", "BuildProxy"]) + } + + override DataFlow::Node getRequestUrl() { result = this.getArgument(0) } + } +} diff --git a/ql/src/semmle/go/security/OpenUrlRedirectCustomizations.qll b/ql/src/semmle/go/security/OpenUrlRedirectCustomizations.qll index ba88143eb80..f32efb143cd 100644 --- a/ql/src/semmle/go/security/OpenUrlRedirectCustomizations.qll +++ b/ql/src/semmle/go/security/OpenUrlRedirectCustomizations.qll @@ -7,6 +7,7 @@ import go import UrlConcatenation import SafeUrlFlowCustomizations +import semmle.go.dataflow.BarrierGuardUtil /** * Provides extension points for customizing the taint-tracking configuration for reasoning about @@ -104,62 +105,22 @@ module OpenUrlRedirect { /** * A call to a function called `isLocalUrl`, `isValidRedirect`, or similar, which is - * considered a barrier for purposes of URL redirection. + * considered a barrier guard for sanitizing untrusted URLs. */ - class RedirectCheckBarrierGuard extends BarrierGuard, DataFlow::CallNode { - RedirectCheckBarrierGuard() { - this.getCalleeName().regexpMatch("(?i)(is_?)?(local_?url|valid_?redir(ect)?)") - } - - override predicate checks(Expr e, boolean outcome) { - // `isLocalUrl(e)` is a barrier for `e` if it evaluates to `true` - getAnArgument().asExpr() = e and - outcome = true - } - } + class RedirectCheckBarrierGuardAsBarrierGuard extends RedirectCheckBarrierGuard, BarrierGuard { } /** - * A check against a constant value, considered a barrier for redirection. - */ - class EqualityTestGuard extends BarrierGuard, DataFlow::EqualityTestNode { - DataFlow::Node url; - - EqualityTestGuard() { - exists(this.getAnOperand().getStringValue()) and - ( - url = this.getAnOperand() - or - exists(DataFlow::MethodCallNode mc | mc = this.getAnOperand() | - mc.getTarget().getName() = "Hostname" and - url = mc.getReceiver() - ) - ) - } - - override predicate checks(Expr e, boolean outcome) { - e = url.asExpr() and outcome = this.getPolarity() - } - } - - /** - * A call to a regexp match function, considered as a barrier guard for unvalidated URLs. + * A call to a regexp match function, considered as a barrier guard for sanitizing untrusted URLs. * * This is overapproximate: we do not attempt to reason about the correctness of the regexp. */ - class RegexpCheck extends BarrierGuard { - RegexpMatchFunction matchfn; - DataFlow::CallNode call; + class RegexpCheckAsBarrierGuard extends RegexpCheck, BarrierGuard { } - RegexpCheck() { - matchfn.getACall() = call and - this = matchfn.getResult().getNode(call).getASuccessor*() - } - - override predicate checks(Expr e, boolean branch) { - e = matchfn.getValue().getNode(call).asExpr() and - (branch = false or branch = true) - } - } + /** + * A check against a constant value or the `Hostname` function, + * considered a barrier guard for url flow. + */ + class UrlCheckAsBarrierGuard extends UrlCheck, BarrierGuard { } } /** A sink for an open redirect, considered as a sink for safe URL flow. */ diff --git a/ql/src/semmle/go/security/RequestForgeryCustomizations.qll b/ql/src/semmle/go/security/RequestForgeryCustomizations.qll index aecd5e077fb..19a0852d2a7 100644 --- a/ql/src/semmle/go/security/RequestForgeryCustomizations.qll +++ b/ql/src/semmle/go/security/RequestForgeryCustomizations.qll @@ -5,6 +5,7 @@ import go import UrlConcatenation import SafeUrlFlowCustomizations +import semmle.go.dataflow.BarrierGuardUtil /** Provides classes and predicates for the request forgery query. */ module RequestForgery { @@ -52,6 +53,19 @@ module RequestForgery { override string getKind() { result = "URL" } } + /** + * The URL of a WebSocket request, viewed as a sink for request forgery. + */ + class WebSocketCallAsSink extends Sink { + WebSocketRequestCall request; + + WebSocketCallAsSink() { this = request.getRequestUrl() } + + override DataFlow::Node getARequest() { result = request } + + override string getKind() { result = "WebSocket URL" } + } + /** * A value that is the result of prepending a string that prevents any value from controlling the * host of a URL. @@ -59,6 +73,29 @@ module RequestForgery { private class HostnameSanitizer extends SanitizerEdge { HostnameSanitizer() { hostnameSanitizingPrefixEdge(this, _) } } + + /** + * A call to a function called `isLocalUrl`, `isValidRedirect`, or similar, which is + * considered a barrier guard. + */ + class RedirectCheckBarrierGuardAsBarrierGuard extends RedirectCheckBarrierGuard, SanitizerGuard { + } + + /** + * A call to a regexp match function, considered as a barrier guard for sanitizing untrusted URLs. + * + * This is overapproximate: we do not attempt to reason about the correctness of the regexp. + */ + class RegexpCheckAsBarrierGuard extends RegexpCheck, SanitizerGuard { } + + /** + * An equality check comparing a data-flow node against a constant string, considered as + * a barrier guard for sanitizing untrusted URLs. + * + * Additionally, a check comparing `url.Hostname()` against a constant string is also + * considered a barrier guard for `url`. + */ + class UrlCheckAsBarrierGuard extends UrlCheck, SanitizerGuard { } } /** A sink for request forgery, considered as a sink for safe URL flow. */ diff --git a/ql/test/library-tests/semmle/go/Packages/packagePredicate.go b/ql/test/library-tests/semmle/go/Packages/packagePredicate.go new file mode 100644 index 00000000000..dc0500dd1a3 --- /dev/null +++ b/ql/test/library-tests/semmle/go/Packages/packagePredicate.go @@ -0,0 +1,22 @@ +package main + +import ( + "fmt" + + _ "PackageName//v//test" // Not OK + _ "PackageName//v/test" // Not OK + _ "PackageName/test" // OK + _ "PackageName/v//test" // Not OK + _ "PackageName/v/asd/v2/test" // Not OK + _ "PackageName/v/test" // Not OK + + _ "PackageName//v2//test" // Not OK + _ "PackageName//v2/test" // Not OK + _ "PackageName/v2//test" // Not OK + _ "PackageName/v2/test" //OK +) + +func main() { + pkg.Foo() + fmt.Println("") +} diff --git a/ql/test/library-tests/semmle/go/Packages/predicate.expected b/ql/test/library-tests/semmle/go/Packages/predicate.expected new file mode 100644 index 00000000000..fb9cf20d4d2 --- /dev/null +++ b/ql/test/library-tests/semmle/go/Packages/predicate.expected @@ -0,0 +1,2 @@ +| package PackageName/test | PackageName/test | +| package PackageName/v2/test | PackageName/v2/test | diff --git a/ql/test/library-tests/semmle/go/Packages/predicate.ql b/ql/test/library-tests/semmle/go/Packages/predicate.ql new file mode 100644 index 00000000000..9a4cdd003ce --- /dev/null +++ b/ql/test/library-tests/semmle/go/Packages/predicate.ql @@ -0,0 +1,8 @@ +import go + +from Package pkg, string mod, string path +where + packages(pkg, _, package(mod, path), _) and + mod = "PackageName" and + path = "test" +select pkg, pkg.getPath() diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/DialFunction.expected b/ql/test/library-tests/semmle/go/frameworks/Websocket/DialFunction.expected new file mode 100644 index 00000000000..e714b20e5d6 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/DialFunction.expected @@ -0,0 +1,9 @@ +| DialFunction.go:25:11:25:52 | call to Dial | DialFunction.go:25:26:25:39 | untrustedInput | +| DialFunction.go:28:12:28:39 | call to DialConfig | DialFunction.go:27:35:27:48 | untrustedInput | +| DialFunction.go:30:2:30:49 | call to Dial | DialFunction.go:30:30:30:43 | untrustedInput | +| DialFunction.go:33:2:33:38 | call to Dial | DialFunction.go:33:14:33:27 | untrustedInput | +| DialFunction.go:35:2:35:61 | call to DialContext | DialFunction.go:35:37:35:50 | untrustedInput | +| DialFunction.go:37:2:37:44 | call to Dial | DialFunction.go:37:30:37:43 | untrustedInput | +| DialFunction.go:40:2:40:45 | call to Dial | DialFunction.go:40:31:40:44 | untrustedInput | +| DialFunction.go:42:2:42:31 | call to BuildProxy | DialFunction.go:42:17:42:30 | untrustedInput | +| DialFunction.go:43:2:43:24 | call to New | DialFunction.go:43:10:43:23 | untrustedInput | diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/DialFunction.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/DialFunction.go new file mode 100644 index 00000000000..520bd08f945 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/DialFunction.go @@ -0,0 +1,45 @@ +package main + +//go:generate depstubber -vendor github.com/gobwas/ws Dialer Dial +//go:generate depstubber -vendor github.com/gorilla/websocket Dialer +//go:generate depstubber -vendor github.com/sacOO7/gowebsocket "" New,BuildProxy +//go:generate depstubber -vendor golang.org/x/net/websocket "" Dial,NewConfig,DialConfig +//go:generate depstubber -vendor nhooyr.io/websocket "" Dial + +import ( + "context" + + gobwas "github.com/gobwas/ws" + gorilla "github.com/gorilla/websocket" + sac "github.com/sacOO7/gowebsocket" + "golang.org/x/net/websocket" + nhooyr "nhooyr.io/websocket" +) + +func main() { + untrustedInput := r.Referer() + + origin := "http://localhost/" + + // bad as input is directly passed to dial function + ws, _ := websocket.Dial(untrustedInput, "", origin) + + config, _ := websocket.NewConfig(untrustedInput, origin) // good + ws2, _ := websocket.DialConfig(config) + + nhooyr.Dial(context.TODO(), untrustedInput, nil) + + dialer := gorilla.Dialer{} + dialer.Dial(untrustedInput, r.Header) + + dialer.DialContext(context.TODO(), untrustedInput, r.Header) + + gobwas.Dial(context.TODO(), untrustedInput) + + dialer2 := gobwas.Dialer{} + dialer2.Dial(context.TODO(), untrustedInput) + + sac.BuildProxy(untrustedInput) + sac.New(untrustedInput) + +} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/DialFunction.ql b/ql/test/library-tests/semmle/go/frameworks/Websocket/DialFunction.ql new file mode 100644 index 00000000000..d6545ca87e6 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/DialFunction.ql @@ -0,0 +1,4 @@ +import go + +from WebSocketRequestCall::Range r +select r, r.getRequestUrl() diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/go.mod b/ql/test/library-tests/semmle/go/frameworks/Websocket/go.mod new file mode 100644 index 00000000000..ce6c493a190 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/go.mod @@ -0,0 +1,11 @@ +module main + +go 1.14 + +require ( + github.com/gobwas/ws v1.0.3 + github.com/gorilla/websocket v1.4.2 + github.com/sacOO7/gowebsocket v0.0.0-20180719182212-1436bb906a4e + golang.org/x/net v0.0.0-20200421231249-e086a090c8fd + nhooyr.io/websocket v1.8.5 +) diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/LICENSE b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/LICENSE new file mode 100644 index 00000000000..d2611fddf55 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017-2018 Sergey Kamardin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/stub.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/stub.go new file mode 100644 index 00000000000..0d00bc949fb --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/stub.go @@ -0,0 +1,54 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for github.com/gobwas/ws, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: github.com/gobwas/ws (exports: Dialer; functions: Dial) + +// Package ws is a stub of github.com/gobwas/ws, generated by depstubber. +package ws + +import ( + bufio "bufio" + context "context" + tls "crypto/tls" + io "io" + net "net" + url "net/url" + time "time" +) + +func Dial(_ context.Context, _ string) (net.Conn, *bufio.Reader, Handshake, error) { + return nil, nil, Handshake{}, nil +} + +type Dialer struct { + ReadBufferSize int + WriteBufferSize int + Timeout time.Duration + Protocols []string + Extensions []interface{} + Header HandshakeHeader + OnStatusError func(int, []byte, io.Reader) + OnHeader func([]byte, []byte) error + NetDial func(context.Context, string, string) (net.Conn, error) + TLSClient func(net.Conn, string) net.Conn + TLSConfig *tls.Config + WrapConn func(net.Conn) net.Conn +} + +func (_ Dialer) Dial(_ context.Context, _ string) (net.Conn, *bufio.Reader, Handshake, error) { + return nil, nil, Handshake{}, nil +} + +func (_ Dialer) Upgrade(_ io.ReadWriter, _ *url.URL) (*bufio.Reader, Handshake, error) { + return nil, Handshake{}, nil +} + +type Handshake struct { + Protocol string + Extensions []interface{} +} + +type HandshakeHeader interface { + WriteTo(_ io.Writer) (int64, error) +} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/LICENSE b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/LICENSE new file mode 100644 index 00000000000..9171c972252 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/stub.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/stub.go new file mode 100644 index 00000000000..0be1589cca9 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/stub.go @@ -0,0 +1,135 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for github.com/gorilla/websocket, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: github.com/gorilla/websocket (exports: Dialer; functions: ) + +// Package websocket is a stub of github.com/gorilla/websocket, generated by depstubber. +package websocket + +import ( + context "context" + tls "crypto/tls" + io "io" + net "net" + http "net/http" + url "net/url" + time "time" +) + +type BufferPool interface { + Get() interface{} + Put(_ interface{}) +} + +type Conn struct{} + +func (_ *Conn) Close() error { + return nil +} + +func (_ *Conn) CloseHandler() func(int, string) error { + return nil +} + +func (_ *Conn) EnableWriteCompression(_ bool) {} + +func (_ *Conn) LocalAddr() net.Addr { + return nil +} + +func (_ *Conn) NextReader() (int, io.Reader, error) { + return 0, nil, nil +} + +func (_ *Conn) NextWriter(_ int) (io.WriteCloser, error) { + return nil, nil +} + +func (_ *Conn) PingHandler() func(string) error { + return nil +} + +func (_ *Conn) PongHandler() func(string) error { + return nil +} + +func (_ *Conn) ReadJSON(_ interface{}) error { + return nil +} + +func (_ *Conn) ReadMessage() (int, []byte, error) { + return 0, nil, nil +} + +func (_ *Conn) RemoteAddr() net.Addr { + return nil +} + +func (_ *Conn) SetCloseHandler(_ func(int, string) error) {} + +func (_ *Conn) SetCompressionLevel(_ int) error { + return nil +} + +func (_ *Conn) SetPingHandler(_ func(string) error) {} + +func (_ *Conn) SetPongHandler(_ func(string) error) {} + +func (_ *Conn) SetReadDeadline(_ time.Time) error { + return nil +} + +func (_ *Conn) SetReadLimit(_ int64) {} + +func (_ *Conn) SetWriteDeadline(_ time.Time) error { + return nil +} + +func (_ *Conn) Subprotocol() string { + return "" +} + +func (_ *Conn) UnderlyingConn() net.Conn { + return nil +} + +func (_ *Conn) WriteControl(_ int, _ []byte, _ time.Time) error { + return nil +} + +func (_ *Conn) WriteJSON(_ interface{}) error { + return nil +} + +func (_ *Conn) WriteMessage(_ int, _ []byte) error { + return nil +} + +func (_ *Conn) WritePreparedMessage(_ *PreparedMessage) error { + return nil +} + +type Dialer struct { + NetDial func(string, string) (net.Conn, error) + NetDialContext func(context.Context, string, string) (net.Conn, error) + Proxy func(*http.Request) (*url.URL, error) + TLSClientConfig *tls.Config + HandshakeTimeout time.Duration + ReadBufferSize int + WriteBufferSize int + WriteBufferPool BufferPool + Subprotocols []string + EnableCompression bool + Jar http.CookieJar +} + +func (_ *Dialer) Dial(_ string, _ http.Header) (*Conn, *http.Response, error) { + return nil, nil, nil +} + +func (_ *Dialer) DialContext(_ context.Context, _ string, _ http.Header) (*Conn, *http.Response, error) { + return nil, nil, nil +} + +type PreparedMessage struct{} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/LICENSE b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/LICENSE new file mode 100644 index 00000000000..95ab2c9a687 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018 Sachin Shinde + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/stub.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/stub.go new file mode 100644 index 00000000000..f1f20c86857 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/stub.go @@ -0,0 +1,58 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for github.com/sacOO7/gowebsocket, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: github.com/sacOO7/gowebsocket (exports: ; functions: New,BuildProxy) + +// Package gowebsocket is a stub of github.com/sacOO7/gowebsocket, generated by depstubber. +package gowebsocket + +import ( + http "net/http" + url "net/url" +) + +func BuildProxy(_ string) func(*http.Request) (*url.URL, error) { + return nil +} + +type ConnectionOptions struct { + UseCompression bool + UseSSL bool + Proxy func(*http.Request) (*url.URL, error) + Subprotocols []string +} + +func New(_ string) Socket { + return Socket{} +} + +type Socket struct { + Conn interface{} + WebsocketDialer interface{} + Url string + ConnectionOptions ConnectionOptions + RequestHeader http.Header + OnConnected func(Socket) + OnTextMessage func(string, Socket) + OnBinaryMessage func([]byte, Socket) + OnConnectError func(error, Socket) + OnDisconnected func(error, Socket) + OnPingReceived func(string, Socket) + OnPongReceived func(string, Socket) + IsConnected bool +} + +func (_ Socket) EnableLogging() {} + +func (_ Socket) GetLogger() interface{} { + return nil +} + +func (_ *Socket) Close() {} + +func (_ *Socket) Connect() {} + +func (_ *Socket) SendBinary(_ []byte) {} + +func (_ *Socket) SendText(_ string) {} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/LICENSE b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/LICENSE new file mode 100644 index 00000000000..6a66aea5eaf --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/stub.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/stub.go new file mode 100644 index 00000000000..b860854e6e8 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/stub.go @@ -0,0 +1,120 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for golang.org/x/net/websocket, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: golang.org/x/net/websocket (exports: ; functions: Dial,NewConfig,DialConfig) + +// Package websocket is a stub of golang.org/x/net/websocket, generated by depstubber. +package websocket + +import ( + tls "crypto/tls" + io "io" + net "net" + http "net/http" + url "net/url" + time "time" +) + +type Config struct { + Location *url.URL + Origin *url.URL + Protocol []string + Version int + TlsConfig *tls.Config + Header http.Header + Dialer *net.Dialer +} + +type Conn struct { + PayloadType byte + MaxPayloadBytes int +} + +func (_ Conn) HandleFrame(_ interface{}) (interface{}, error) { + return nil, nil +} + +func (_ Conn) HeaderReader() io.Reader { + return nil +} + +func (_ Conn) Len() int { + return 0 +} + +func (_ Conn) NewFrameReader() (interface{}, error) { + return nil, nil +} + +func (_ Conn) NewFrameWriter(_ byte) (interface{}, error) { + return nil, nil +} + +func (_ Conn) TrailerReader() io.Reader { + return nil +} + +func (_ Conn) WriteClose(_ int) error { + return nil +} + +func (_ *Conn) Close() error { + return nil +} + +func (_ *Conn) Config() *Config { + return nil +} + +func (_ *Conn) IsClientConn() bool { + return false +} + +func (_ *Conn) IsServerConn() bool { + return false +} + +func (_ *Conn) LocalAddr() net.Addr { + return nil +} + +func (_ *Conn) Read(_ []byte) (int, error) { + return 0, nil +} + +func (_ *Conn) RemoteAddr() net.Addr { + return nil +} + +func (_ *Conn) Request() *http.Request { + return nil +} + +func (_ *Conn) SetDeadline(_ time.Time) error { + return nil +} + +func (_ *Conn) SetReadDeadline(_ time.Time) error { + return nil +} + +func (_ *Conn) SetWriteDeadline(_ time.Time) error { + return nil +} + +func (_ *Conn) Write(_ []byte) (int, error) { + return 0, nil +} + +func Dial(_ string, _ string, _ string) (*Conn, error) { + return nil, nil +} + +func DialConfig(_ *Config) (*Conn, error) { + return nil, nil +} + +func NewConfig(_ string, _ string) (*Config, error) { + return nil, nil +} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/modules.txt b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/modules.txt new file mode 100644 index 00000000000..319b30b771b --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/modules.txt @@ -0,0 +1,15 @@ +# github.com/gobwas/ws v1.0.3 +## explicit +github.com/gobwas/ws +# github.com/gorilla/websocket v1.4.2 +## explicit +github.com/gorilla/websocket +# github.com/sacOO7/gowebsocket v0.0.0-20180719182212-1436bb906a4e +## explicit +github.com/sacOO7/gowebsocket +# golang.org/x/net v0.0.0-20200421231249-e086a090c8fd +## explicit +golang.org/x/net +# nhooyr.io/websocket v1.8.5 +## explicit +nhooyr.io/websocket diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/LICENSE b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/LICENSE new file mode 100644 index 00000000000..b5b5fef31f0 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Anmol Sethi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/stub.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/stub.go new file mode 100644 index 00000000000..7bf2a208dac --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/stub.go @@ -0,0 +1,76 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for nhooyr.io/websocket, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: nhooyr.io/websocket (exports: ; functions: Dial) + +// Package websocket is a stub of nhooyr.io/websocket, generated by depstubber. +package websocket + +import ( + context "context" + io "io" + http "net/http" +) + +type CompressionMode int + +type Conn struct{} + +func (_ *Conn) Close(_ StatusCode, _ string) error { + return nil +} + +func (_ *Conn) CloseRead(_ context.Context) context.Context { + return nil +} + +func (_ *Conn) Ping(_ context.Context) error { + return nil +} + +func (_ *Conn) Read(_ context.Context) (MessageType, []byte, error) { + return 0, nil, nil +} + +func (_ *Conn) Reader(_ context.Context) (MessageType, io.Reader, error) { + return 0, nil, nil +} + +func (_ *Conn) SetReadLimit(_ int64) {} + +func (_ *Conn) Subprotocol() string { + return "" +} + +func (_ *Conn) Write(_ context.Context, _ MessageType, _ []byte) error { + return nil +} + +func (_ *Conn) Writer(_ context.Context, _ MessageType) (io.WriteCloser, error) { + return nil, nil +} + +func Dial(_ context.Context, _ string, _ *DialOptions) (*Conn, *http.Response, error) { + return nil, nil, nil +} + +type DialOptions struct { + HTTPClient *http.Client + HTTPHeader http.Header + Subprotocols []string + CompressionMode CompressionMode + CompressionThreshold int +} + +type MessageType int + +func (_ MessageType) String() string { + return "" +} + +type StatusCode int + +func (_ StatusCode) String() string { + return "" +} diff --git a/ql/test/query-tests/Security/CWE-918/RequestForgery.expected b/ql/test/query-tests/Security/CWE-918/RequestForgery.expected index 5b8fb08dce1..5709a91dcaf 100644 --- a/ql/test/query-tests/Security/CWE-918/RequestForgery.expected +++ b/ql/test/query-tests/Security/CWE-918/RequestForgery.expected @@ -13,6 +13,15 @@ edges | tst.go:36:2:36:2 | implicit dereference : URL | tst.go:36:2:36:2 | implicit dereference : URL | | tst.go:36:2:36:2 | implicit dereference : URL | tst.go:37:11:37:20 | call to String | | tst.go:36:2:36:2 | u [pointer] : URL | tst.go:36:2:36:2 | implicit dereference : URL | +| websocket.go:60:21:60:31 | call to Referer : string | websocket.go:65:27:65:40 | untrustedInput | +| websocket.go:74:21:74:31 | call to Referer : string | websocket.go:78:36:78:49 | untrustedInput | +| websocket.go:88:21:88:31 | call to Referer : string | websocket.go:91:31:91:44 | untrustedInput | +| websocket.go:107:21:107:31 | call to Referer : string | websocket.go:110:15:110:28 | untrustedInput | +| websocket.go:126:21:126:31 | call to Referer : string | websocket.go:129:38:129:51 | untrustedInput | +| websocket.go:154:21:154:31 | call to Referer : string | websocket.go:155:31:155:44 | untrustedInput | +| websocket.go:160:21:160:31 | call to Referer : string | websocket.go:162:31:162:44 | untrustedInput | +| websocket.go:195:21:195:31 | call to Referer : string | websocket.go:197:18:197:31 | untrustedInput | +| websocket.go:202:21:202:31 | call to Referer : string | websocket.go:204:11:204:24 | untrustedInput | nodes | RequestForgery.go:8:12:8:34 | call to FormValue : string | semmle.label | call to FormValue : string | | RequestForgery.go:11:24:11:65 | ...+... | semmle.label | ...+... | @@ -27,6 +36,24 @@ nodes | tst.go:36:2:36:2 | implicit dereference : URL | semmle.label | implicit dereference : URL | | tst.go:36:2:36:2 | u [pointer] : URL | semmle.label | u [pointer] : URL | | tst.go:37:11:37:20 | call to String | semmle.label | call to String | +| websocket.go:60:21:60:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:65:27:65:40 | untrustedInput | semmle.label | untrustedInput | +| websocket.go:74:21:74:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:78:36:78:49 | untrustedInput | semmle.label | untrustedInput | +| websocket.go:88:21:88:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:91:31:91:44 | untrustedInput | semmle.label | untrustedInput | +| websocket.go:107:21:107:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:110:15:110:28 | untrustedInput | semmle.label | untrustedInput | +| websocket.go:126:21:126:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:129:38:129:51 | untrustedInput | semmle.label | untrustedInput | +| websocket.go:154:21:154:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:155:31:155:44 | untrustedInput | semmle.label | untrustedInput | +| websocket.go:160:21:160:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:162:31:162:44 | untrustedInput | semmle.label | untrustedInput | +| websocket.go:195:21:195:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:197:18:197:31 | untrustedInput | semmle.label | untrustedInput | +| websocket.go:202:21:202:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:204:11:204:24 | untrustedInput | semmle.label | untrustedInput | #select | RequestForgery.go:11:15:11:66 | call to Get | RequestForgery.go:8:12:8:34 | call to FormValue : string | RequestForgery.go:11:24:11:65 | ...+... | The $@ of this request depends on $@. | RequestForgery.go:11:24:11:65 | ...+... | URL | RequestForgery.go:8:12:8:34 | call to FormValue : string | a user-provided value | | tst.go:14:2:14:18 | call to Get | tst.go:10:13:10:35 | call to FormValue : string | tst.go:14:11:14:17 | tainted | The $@ of this request depends on $@. | tst.go:14:11:14:17 | tainted | URL | tst.go:10:13:10:35 | call to FormValue : string | a user-provided value | @@ -36,3 +63,12 @@ nodes | tst.go:27:2:27:30 | call to Get | tst.go:10:13:10:35 | call to FormValue : string | tst.go:27:11:27:29 | ...+... | The $@ of this request depends on $@. | tst.go:27:11:27:29 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue : string | a user-provided value | | tst.go:29:2:29:41 | call to Get | tst.go:10:13:10:35 | call to FormValue : string | tst.go:29:11:29:40 | ...+... | The $@ of this request depends on $@. | tst.go:29:11:29:40 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue : string | a user-provided value | | tst.go:37:2:37:21 | call to Get | tst.go:10:13:10:35 | call to FormValue : string | tst.go:37:11:37:20 | call to String | The $@ of this request depends on $@. | tst.go:37:11:37:20 | call to String | URL | tst.go:10:13:10:35 | call to FormValue : string | a user-provided value | +| websocket.go:65:12:65:53 | call to Dial | websocket.go:60:21:60:31 | call to Referer : string | websocket.go:65:27:65:40 | untrustedInput | The $@ of this request depends on $@. | websocket.go:65:27:65:40 | untrustedInput | WebSocket URL | websocket.go:60:21:60:31 | call to Referer : string | a user-provided value | +| websocket.go:79:13:79:40 | call to DialConfig | websocket.go:74:21:74:31 | call to Referer : string | websocket.go:78:36:78:49 | untrustedInput | The $@ of this request depends on $@. | websocket.go:78:36:78:49 | untrustedInput | WebSocket URL | websocket.go:74:21:74:31 | call to Referer : string | a user-provided value | +| websocket.go:91:3:91:50 | call to Dial | websocket.go:88:21:88:31 | call to Referer : string | websocket.go:91:31:91:44 | untrustedInput | The $@ of this request depends on $@. | websocket.go:91:31:91:44 | untrustedInput | WebSocket URL | websocket.go:88:21:88:31 | call to Referer : string | a user-provided value | +| websocket.go:110:3:110:39 | call to Dial | websocket.go:107:21:107:31 | call to Referer : string | websocket.go:110:15:110:28 | untrustedInput | The $@ of this request depends on $@. | websocket.go:110:15:110:28 | untrustedInput | WebSocket URL | websocket.go:107:21:107:31 | call to Referer : string | a user-provided value | +| websocket.go:129:3:129:62 | call to DialContext | websocket.go:126:21:126:31 | call to Referer : string | websocket.go:129:38:129:51 | untrustedInput | The $@ of this request depends on $@. | websocket.go:129:38:129:51 | untrustedInput | WebSocket URL | websocket.go:126:21:126:31 | call to Referer : string | a user-provided value | +| websocket.go:155:3:155:45 | call to Dial | websocket.go:154:21:154:31 | call to Referer : string | websocket.go:155:31:155:44 | untrustedInput | The $@ of this request depends on $@. | websocket.go:155:31:155:44 | untrustedInput | WebSocket URL | websocket.go:154:21:154:31 | call to Referer : string | a user-provided value | +| websocket.go:162:3:162:45 | call to Dial | websocket.go:160:21:160:31 | call to Referer : string | websocket.go:162:31:162:44 | untrustedInput | The $@ of this request depends on $@. | websocket.go:162:31:162:44 | untrustedInput | WebSocket URL | websocket.go:160:21:160:31 | call to Referer : string | a user-provided value | +| websocket.go:197:3:197:32 | call to BuildProxy | websocket.go:195:21:195:31 | call to Referer : string | websocket.go:197:18:197:31 | untrustedInput | The $@ of this request depends on $@. | websocket.go:197:18:197:31 | untrustedInput | WebSocket URL | websocket.go:195:21:195:31 | call to Referer : string | a user-provided value | +| websocket.go:204:3:204:25 | call to New | websocket.go:202:21:202:31 | call to Referer : string | websocket.go:204:11:204:24 | untrustedInput | The $@ of this request depends on $@. | websocket.go:204:11:204:24 | untrustedInput | WebSocket URL | websocket.go:202:21:202:31 | call to Referer : string | a user-provided value | diff --git a/ql/test/query-tests/Security/CWE-918/go.mod b/ql/test/query-tests/Security/CWE-918/go.mod new file mode 100644 index 00000000000..ce6c493a190 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-918/go.mod @@ -0,0 +1,11 @@ +module main + +go 1.14 + +require ( + github.com/gobwas/ws v1.0.3 + github.com/gorilla/websocket v1.4.2 + github.com/sacOO7/gowebsocket v0.0.0-20180719182212-1436bb906a4e + golang.org/x/net v0.0.0-20200421231249-e086a090c8fd + nhooyr.io/websocket v1.8.5 +) diff --git a/ql/test/query-tests/Security/CWE-918/main b/ql/test/query-tests/Security/CWE-918/main new file mode 100755 index 00000000000..e713a460ed5 Binary files /dev/null and b/ql/test/query-tests/Security/CWE-918/main differ diff --git a/ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/LICENSE b/ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/LICENSE new file mode 100644 index 00000000000..d2611fddf55 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017-2018 Sergey Kamardin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/stub.go b/ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/stub.go new file mode 100644 index 00000000000..0d00bc949fb --- /dev/null +++ b/ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/stub.go @@ -0,0 +1,54 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for github.com/gobwas/ws, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: github.com/gobwas/ws (exports: Dialer; functions: Dial) + +// Package ws is a stub of github.com/gobwas/ws, generated by depstubber. +package ws + +import ( + bufio "bufio" + context "context" + tls "crypto/tls" + io "io" + net "net" + url "net/url" + time "time" +) + +func Dial(_ context.Context, _ string) (net.Conn, *bufio.Reader, Handshake, error) { + return nil, nil, Handshake{}, nil +} + +type Dialer struct { + ReadBufferSize int + WriteBufferSize int + Timeout time.Duration + Protocols []string + Extensions []interface{} + Header HandshakeHeader + OnStatusError func(int, []byte, io.Reader) + OnHeader func([]byte, []byte) error + NetDial func(context.Context, string, string) (net.Conn, error) + TLSClient func(net.Conn, string) net.Conn + TLSConfig *tls.Config + WrapConn func(net.Conn) net.Conn +} + +func (_ Dialer) Dial(_ context.Context, _ string) (net.Conn, *bufio.Reader, Handshake, error) { + return nil, nil, Handshake{}, nil +} + +func (_ Dialer) Upgrade(_ io.ReadWriter, _ *url.URL) (*bufio.Reader, Handshake, error) { + return nil, Handshake{}, nil +} + +type Handshake struct { + Protocol string + Extensions []interface{} +} + +type HandshakeHeader interface { + WriteTo(_ io.Writer) (int64, error) +} diff --git a/ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/LICENSE b/ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/LICENSE new file mode 100644 index 00000000000..9171c972252 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/stub.go b/ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/stub.go new file mode 100644 index 00000000000..0be1589cca9 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/stub.go @@ -0,0 +1,135 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for github.com/gorilla/websocket, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: github.com/gorilla/websocket (exports: Dialer; functions: ) + +// Package websocket is a stub of github.com/gorilla/websocket, generated by depstubber. +package websocket + +import ( + context "context" + tls "crypto/tls" + io "io" + net "net" + http "net/http" + url "net/url" + time "time" +) + +type BufferPool interface { + Get() interface{} + Put(_ interface{}) +} + +type Conn struct{} + +func (_ *Conn) Close() error { + return nil +} + +func (_ *Conn) CloseHandler() func(int, string) error { + return nil +} + +func (_ *Conn) EnableWriteCompression(_ bool) {} + +func (_ *Conn) LocalAddr() net.Addr { + return nil +} + +func (_ *Conn) NextReader() (int, io.Reader, error) { + return 0, nil, nil +} + +func (_ *Conn) NextWriter(_ int) (io.WriteCloser, error) { + return nil, nil +} + +func (_ *Conn) PingHandler() func(string) error { + return nil +} + +func (_ *Conn) PongHandler() func(string) error { + return nil +} + +func (_ *Conn) ReadJSON(_ interface{}) error { + return nil +} + +func (_ *Conn) ReadMessage() (int, []byte, error) { + return 0, nil, nil +} + +func (_ *Conn) RemoteAddr() net.Addr { + return nil +} + +func (_ *Conn) SetCloseHandler(_ func(int, string) error) {} + +func (_ *Conn) SetCompressionLevel(_ int) error { + return nil +} + +func (_ *Conn) SetPingHandler(_ func(string) error) {} + +func (_ *Conn) SetPongHandler(_ func(string) error) {} + +func (_ *Conn) SetReadDeadline(_ time.Time) error { + return nil +} + +func (_ *Conn) SetReadLimit(_ int64) {} + +func (_ *Conn) SetWriteDeadline(_ time.Time) error { + return nil +} + +func (_ *Conn) Subprotocol() string { + return "" +} + +func (_ *Conn) UnderlyingConn() net.Conn { + return nil +} + +func (_ *Conn) WriteControl(_ int, _ []byte, _ time.Time) error { + return nil +} + +func (_ *Conn) WriteJSON(_ interface{}) error { + return nil +} + +func (_ *Conn) WriteMessage(_ int, _ []byte) error { + return nil +} + +func (_ *Conn) WritePreparedMessage(_ *PreparedMessage) error { + return nil +} + +type Dialer struct { + NetDial func(string, string) (net.Conn, error) + NetDialContext func(context.Context, string, string) (net.Conn, error) + Proxy func(*http.Request) (*url.URL, error) + TLSClientConfig *tls.Config + HandshakeTimeout time.Duration + ReadBufferSize int + WriteBufferSize int + WriteBufferPool BufferPool + Subprotocols []string + EnableCompression bool + Jar http.CookieJar +} + +func (_ *Dialer) Dial(_ string, _ http.Header) (*Conn, *http.Response, error) { + return nil, nil, nil +} + +func (_ *Dialer) DialContext(_ context.Context, _ string, _ http.Header) (*Conn, *http.Response, error) { + return nil, nil, nil +} + +type PreparedMessage struct{} diff --git a/ql/test/query-tests/Security/CWE-918/vendor/github.com/sacOO7/gowebsocket/LICENSE b/ql/test/query-tests/Security/CWE-918/vendor/github.com/sacOO7/gowebsocket/LICENSE new file mode 100644 index 00000000000..95ab2c9a687 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-918/vendor/github.com/sacOO7/gowebsocket/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018 Sachin Shinde + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/ql/test/query-tests/Security/CWE-918/vendor/github.com/sacOO7/gowebsocket/stub.go b/ql/test/query-tests/Security/CWE-918/vendor/github.com/sacOO7/gowebsocket/stub.go new file mode 100644 index 00000000000..f1f20c86857 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-918/vendor/github.com/sacOO7/gowebsocket/stub.go @@ -0,0 +1,58 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for github.com/sacOO7/gowebsocket, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: github.com/sacOO7/gowebsocket (exports: ; functions: New,BuildProxy) + +// Package gowebsocket is a stub of github.com/sacOO7/gowebsocket, generated by depstubber. +package gowebsocket + +import ( + http "net/http" + url "net/url" +) + +func BuildProxy(_ string) func(*http.Request) (*url.URL, error) { + return nil +} + +type ConnectionOptions struct { + UseCompression bool + UseSSL bool + Proxy func(*http.Request) (*url.URL, error) + Subprotocols []string +} + +func New(_ string) Socket { + return Socket{} +} + +type Socket struct { + Conn interface{} + WebsocketDialer interface{} + Url string + ConnectionOptions ConnectionOptions + RequestHeader http.Header + OnConnected func(Socket) + OnTextMessage func(string, Socket) + OnBinaryMessage func([]byte, Socket) + OnConnectError func(error, Socket) + OnDisconnected func(error, Socket) + OnPingReceived func(string, Socket) + OnPongReceived func(string, Socket) + IsConnected bool +} + +func (_ Socket) EnableLogging() {} + +func (_ Socket) GetLogger() interface{} { + return nil +} + +func (_ *Socket) Close() {} + +func (_ *Socket) Connect() {} + +func (_ *Socket) SendBinary(_ []byte) {} + +func (_ *Socket) SendText(_ string) {} diff --git a/ql/test/query-tests/Security/CWE-918/vendor/golang.org/x/net/websocket/LICENSE b/ql/test/query-tests/Security/CWE-918/vendor/golang.org/x/net/websocket/LICENSE new file mode 100644 index 00000000000..6a66aea5eaf --- /dev/null +++ b/ql/test/query-tests/Security/CWE-918/vendor/golang.org/x/net/websocket/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ql/test/query-tests/Security/CWE-918/vendor/golang.org/x/net/websocket/stub.go b/ql/test/query-tests/Security/CWE-918/vendor/golang.org/x/net/websocket/stub.go new file mode 100644 index 00000000000..b860854e6e8 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-918/vendor/golang.org/x/net/websocket/stub.go @@ -0,0 +1,120 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for golang.org/x/net/websocket, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: golang.org/x/net/websocket (exports: ; functions: Dial,NewConfig,DialConfig) + +// Package websocket is a stub of golang.org/x/net/websocket, generated by depstubber. +package websocket + +import ( + tls "crypto/tls" + io "io" + net "net" + http "net/http" + url "net/url" + time "time" +) + +type Config struct { + Location *url.URL + Origin *url.URL + Protocol []string + Version int + TlsConfig *tls.Config + Header http.Header + Dialer *net.Dialer +} + +type Conn struct { + PayloadType byte + MaxPayloadBytes int +} + +func (_ Conn) HandleFrame(_ interface{}) (interface{}, error) { + return nil, nil +} + +func (_ Conn) HeaderReader() io.Reader { + return nil +} + +func (_ Conn) Len() int { + return 0 +} + +func (_ Conn) NewFrameReader() (interface{}, error) { + return nil, nil +} + +func (_ Conn) NewFrameWriter(_ byte) (interface{}, error) { + return nil, nil +} + +func (_ Conn) TrailerReader() io.Reader { + return nil +} + +func (_ Conn) WriteClose(_ int) error { + return nil +} + +func (_ *Conn) Close() error { + return nil +} + +func (_ *Conn) Config() *Config { + return nil +} + +func (_ *Conn) IsClientConn() bool { + return false +} + +func (_ *Conn) IsServerConn() bool { + return false +} + +func (_ *Conn) LocalAddr() net.Addr { + return nil +} + +func (_ *Conn) Read(_ []byte) (int, error) { + return 0, nil +} + +func (_ *Conn) RemoteAddr() net.Addr { + return nil +} + +func (_ *Conn) Request() *http.Request { + return nil +} + +func (_ *Conn) SetDeadline(_ time.Time) error { + return nil +} + +func (_ *Conn) SetReadDeadline(_ time.Time) error { + return nil +} + +func (_ *Conn) SetWriteDeadline(_ time.Time) error { + return nil +} + +func (_ *Conn) Write(_ []byte) (int, error) { + return 0, nil +} + +func Dial(_ string, _ string, _ string) (*Conn, error) { + return nil, nil +} + +func DialConfig(_ *Config) (*Conn, error) { + return nil, nil +} + +func NewConfig(_ string, _ string) (*Config, error) { + return nil, nil +} diff --git a/ql/test/query-tests/Security/CWE-918/vendor/modules.txt b/ql/test/query-tests/Security/CWE-918/vendor/modules.txt new file mode 100644 index 00000000000..319b30b771b --- /dev/null +++ b/ql/test/query-tests/Security/CWE-918/vendor/modules.txt @@ -0,0 +1,15 @@ +# github.com/gobwas/ws v1.0.3 +## explicit +github.com/gobwas/ws +# github.com/gorilla/websocket v1.4.2 +## explicit +github.com/gorilla/websocket +# github.com/sacOO7/gowebsocket v0.0.0-20180719182212-1436bb906a4e +## explicit +github.com/sacOO7/gowebsocket +# golang.org/x/net v0.0.0-20200421231249-e086a090c8fd +## explicit +golang.org/x/net +# nhooyr.io/websocket v1.8.5 +## explicit +nhooyr.io/websocket diff --git a/ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/LICENSE b/ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/LICENSE new file mode 100644 index 00000000000..b5b5fef31f0 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Anmol Sethi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/stub.go b/ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/stub.go new file mode 100644 index 00000000000..7bf2a208dac --- /dev/null +++ b/ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/stub.go @@ -0,0 +1,76 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for nhooyr.io/websocket, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: nhooyr.io/websocket (exports: ; functions: Dial) + +// Package websocket is a stub of nhooyr.io/websocket, generated by depstubber. +package websocket + +import ( + context "context" + io "io" + http "net/http" +) + +type CompressionMode int + +type Conn struct{} + +func (_ *Conn) Close(_ StatusCode, _ string) error { + return nil +} + +func (_ *Conn) CloseRead(_ context.Context) context.Context { + return nil +} + +func (_ *Conn) Ping(_ context.Context) error { + return nil +} + +func (_ *Conn) Read(_ context.Context) (MessageType, []byte, error) { + return 0, nil, nil +} + +func (_ *Conn) Reader(_ context.Context) (MessageType, io.Reader, error) { + return 0, nil, nil +} + +func (_ *Conn) SetReadLimit(_ int64) {} + +func (_ *Conn) Subprotocol() string { + return "" +} + +func (_ *Conn) Write(_ context.Context, _ MessageType, _ []byte) error { + return nil +} + +func (_ *Conn) Writer(_ context.Context, _ MessageType) (io.WriteCloser, error) { + return nil, nil +} + +func Dial(_ context.Context, _ string, _ *DialOptions) (*Conn, *http.Response, error) { + return nil, nil, nil +} + +type DialOptions struct { + HTTPClient *http.Client + HTTPHeader http.Header + Subprotocols []string + CompressionMode CompressionMode + CompressionThreshold int +} + +type MessageType int + +func (_ MessageType) String() string { + return "" +} + +type StatusCode int + +func (_ StatusCode) String() string { + return "" +} diff --git a/ql/test/query-tests/Security/CWE-918/websocket.go b/ql/test/query-tests/Security/CWE-918/websocket.go new file mode 100644 index 00000000000..db613fe5fa5 --- /dev/null +++ b/ql/test/query-tests/Security/CWE-918/websocket.go @@ -0,0 +1,209 @@ +package main + +//go:generate depstubber -vendor github.com/gobwas/ws Dialer Dial +//go:generate depstubber -vendor github.com/gorilla/websocket Dialer +//go:generate depstubber -vendor github.com/sacOO7/gowebsocket "" New,BuildProxy +//go:generate depstubber -vendor golang.org/x/net/websocket "" Dial,NewConfig,DialConfig +//go:generate depstubber -vendor nhooyr.io/websocket "" Dial + +import ( + "context" + "fmt" + "log" + "net/http" + "regexp" + "strings" + + gobwas "github.com/gobwas/ws" + gorilla "github.com/gorilla/websocket" + sac "github.com/sacOO7/gowebsocket" + "golang.org/x/net/websocket" + nhooyr "nhooyr.io/websocket" +) + +func test() { + // x net websocket Dial good + http.HandleFunc("/ex0", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + + origin := "http://localhost/" + + untrustedInputTrimmed := strings.TrimRight(untrustedInput, "\n\r") + if untrustedInputTrimmed == "ws://localhost:12345/ws" { + // good as input is checked against fixed set of urls. + ws, _ := websocket.Dial(untrustedInputTrimmed, "", origin) + var msg = make([]byte, 512) + var n int + n, _ = ws.Read(msg) + fmt.Printf("Received: %s.\n", msg[:n]) + } + }) + + // x net websocket DialConfig good + http.HandleFunc("/ex1", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + + origin := "http://localhost/" + // good as input is tested against a regex + if m, _ := regexp.MatchString("ws://localhost:12345/*", untrustedInput); m { + config, _ := websocket.NewConfig(untrustedInput, origin) // good + ws2, _ := websocket.DialConfig(config) + var msg = make([]byte, 512) + var n int + n, _ = ws2.Read(msg) + fmt.Printf("Received: %s.\n", msg[:n]) + } + }) + + // x net websocket dial bad + http.HandleFunc("/ex2", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + + origin := "http://localhost/" + + // bad as input is directly passed to dial function + ws, _ := websocket.Dial(untrustedInput, "", origin) + var msg = make([]byte, 512) + var n int + n, _ = ws.Read(msg) + fmt.Printf("Received: %s.\n", msg[:n]) + }) + + // x net websocket dialConfig bad + http.HandleFunc("/ex3", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + + origin := "http://localhost/" + // bad as input is directly used + config, _ := websocket.NewConfig(untrustedInput, origin) // good + ws2, _ := websocket.DialConfig(config) + var msg = make([]byte, 512) + var n int + n, _ = ws2.Read(msg) + fmt.Printf("Received: %s.\n", msg[:n]) + }) + + // nhooyr websocket dial bad + http.HandleFunc("/ex4", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + + // bad as input is used directly + nhooyr.Dial(context.TODO(), untrustedInput, nil) + w.WriteHeader(500) + }) + + // nhooyr websocket dial good + http.HandleFunc("/ex5", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + + // good as input is tested againt regex + if m, _ := regexp.MatchString("ws://localhost:12345/*", untrustedInput); m { + nhooyr.Dial(context.TODO(), untrustedInput, nil) + } + }) + + // gorilla websocket Dialer.Dial bad + http.HandleFunc("/ex6", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + + dialer := gorilla.Dialer{} + dialer.Dial(untrustedInput, r.Header) + }) + + // gorilla websocket Dialer.Dial good + http.HandleFunc("/ex7", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + + if untrustedInput == "localhost" { + + dialer := gorilla.Dialer{} + dialer.Dial(untrustedInput, r.Header) + } + }) + + // gorilla websocket Dialer.DialContext bad + http.HandleFunc("/ex8", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + + dialer := gorilla.Dialer{} + dialer.DialContext(context.TODO(), untrustedInput, r.Header) + }) + + // gorilla websocket Dialer.DialContext good + http.HandleFunc("/ex9", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + + if untrustedInput == "localhost" { + + dialer := gorilla.Dialer{} + dialer.DialContext(context.TODO(), untrustedInput, r.Header) + } + }) + + // gobwas websocket Dial good + http.HandleFunc("/ex10", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + + if untrustedInput == "localhost" { + gobwas.Dial(context.TODO(), untrustedInput) + } + }) + + // gobwas websocket Dial bad + http.HandleFunc("/ex11", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + gobwas.Dial(context.TODO(), untrustedInput) + }) + + // gobwas websocket Dialer.Dial bad + http.HandleFunc("/ex12", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + dialer := gobwas.Dialer{} + dialer.Dial(context.TODO(), untrustedInput) + }) + + // gobwas websocket Dialer.Dial good + http.HandleFunc("/ex12", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + + if "localhost" == untrustedInput { + dialer := gobwas.Dialer{} + dialer.Dial(context.TODO(), untrustedInput) + } + }) + + // sac007 websocket New good + http.HandleFunc("/ex13", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + + if "localhost" == untrustedInput { + sac.New(untrustedInput) + } + }) + + // sac007 websocket BuildProxy good + http.HandleFunc("/ex14", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + + if "localhost" == untrustedInput { + sac.BuildProxy(untrustedInput) + } + }) + + // sac007 websocket BuildProxy bad + http.HandleFunc("/ex15", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + + sac.BuildProxy(untrustedInput) + }) + + // sac007 websocket New bad + http.HandleFunc("/ex16", func(w http.ResponseWriter, r *http.Request) { + untrustedInput := r.Referer() + + sac.New(untrustedInput) + }) + + log.Println(http.ListenAndServe(":80", nil)) + +}