From 4dfa9d58c031d75885dc11ea87a8dd330f39c456 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 17 Sep 2020 13:41:20 +0100 Subject: [PATCH] Model Revel --- ql/src/go.qll | 1 + ql/src/semmle/go/frameworks/Revel.qll | 97 +++ ql/src/semmle/go/frameworks/WebSocket.qll | 24 + .../semmle/go/frameworks/Revel/Revel.go | 111 +++ .../go/frameworks/Revel/TaintFlows.expected | 34 + .../semmle/go/frameworks/Revel/TaintFlows.ql | 19 + .../semmle/go/frameworks/Revel/go.mod | 20 + .../vendor/github.com/revel/revel/stub.go | 705 ++++++++++++++++++ .../go/frameworks/Revel/vendor/modules.txt | 42 ++ 9 files changed, 1053 insertions(+) create mode 100644 ql/src/semmle/go/frameworks/Revel.qll create mode 100644 ql/test/library-tests/semmle/go/frameworks/Revel/Revel.go create mode 100644 ql/test/library-tests/semmle/go/frameworks/Revel/TaintFlows.expected create mode 100644 ql/test/library-tests/semmle/go/frameworks/Revel/TaintFlows.ql create mode 100644 ql/test/library-tests/semmle/go/frameworks/Revel/go.mod create mode 100644 ql/test/library-tests/semmle/go/frameworks/Revel/vendor/github.com/revel/revel/stub.go create mode 100644 ql/test/library-tests/semmle/go/frameworks/Revel/vendor/modules.txt diff --git a/ql/src/go.qll b/ql/src/go.qll index b4b07eff90f..6f400db0537 100644 --- a/ql/src/go.qll +++ b/ql/src/go.qll @@ -39,6 +39,7 @@ import semmle.go.frameworks.Macaron import semmle.go.frameworks.Mux import semmle.go.frameworks.NoSQL import semmle.go.frameworks.Protobuf +import semmle.go.frameworks.Revel import semmle.go.frameworks.Spew import semmle.go.frameworks.SQL import semmle.go.frameworks.Stdlib diff --git a/ql/src/semmle/go/frameworks/Revel.qll b/ql/src/semmle/go/frameworks/Revel.qll new file mode 100644 index 00000000000..365c30fc2ed --- /dev/null +++ b/ql/src/semmle/go/frameworks/Revel.qll @@ -0,0 +1,97 @@ +/** + * Provides classes for working with untrusted flow sources from the `github.com/revel/revel` package. + */ + +import go + +module Revel { + /** Gets the package name. */ + bindingset[result] + string packagePath() { result = package(["github.com/revel", "github.com/robfig"], "revel") } + + private class ControllerParams extends UntrustedFlowSource::Range, DataFlow::FieldReadNode { + ControllerParams() { + exists(Field f | + this.readsField(_, f) and + f.hasQualifiedName(packagePath(), "Controller", "Params") + ) + } + } + + private class ParamsFixedSanitizer extends TaintTracking::DefaultTaintSanitizer, + DataFlow::FieldReadNode { + ParamsFixedSanitizer() { + exists(Field f | + this.readsField(_, f) and + f.hasQualifiedName(packagePath(), "Params", "Fixed") + ) + } + } + + private class ParamsBind extends TaintTracking::FunctionModel, Method { + ParamsBind() { this.hasQualifiedName(packagePath(), "Params", ["Bind", "BindJSON"]) } + + override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { + inp.isReceiver() and outp.isParameter(0) + } + } + + private class RouteMatchParams extends UntrustedFlowSource::Range, DataFlow::FieldReadNode { + RouteMatchParams() { + exists(Field f | + this.readsField(_, f) and + f.hasQualifiedName(packagePath(), "RouteMatch", "Params") + ) + } + } + + /** An access to an HTTP request field whose value may be controlled by an untrusted user. */ + private class UserControlledRequestField extends UntrustedFlowSource::Range, + DataFlow::FieldReadNode { + UserControlledRequestField() { + exists(string fieldName | + this.getField().hasQualifiedName(packagePath(), "Request", fieldName) + | + fieldName in ["In", "Header", "URL", "Form", "MultipartForm"] + ) + } + } + + private class UserControlledRequestMethod extends UntrustedFlowSource::Range, + DataFlow::MethodCallNode { + UserControlledRequestMethod() { + this + .getTarget() + .hasQualifiedName(packagePath(), "Request", + ["FormValue", "PostFormValue", "GetQuery", "GetForm", "GetMultipartForm", "GetBody"]) + } + } + + private class ServerMultipartFormGetFiles extends TaintTracking::FunctionModel, Method { + ServerMultipartFormGetFiles() { + this.hasQualifiedName(packagePath(), "ServerMultipartForm", "GetFiles") + } + + override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { + inp.isReceiver() and outp.isResult() + } + } + + private class ServerMultipartFormGetValues extends TaintTracking::FunctionModel, Method { + ServerMultipartFormGetValues() { + this.hasQualifiedName(packagePath(), "ServerMultipartForm", "GetValues") + } + + override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { + inp.isReceiver() and outp.isResult() + } + } + + private class ServerRequestGet extends TaintTracking::FunctionModel, Method { + ServerRequestGet() { this.hasQualifiedName(packagePath(), "ServerRequest", "Get") } + + override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) { + inp.isReceiver() and outp.isResult(0) + } + } +} diff --git a/ql/src/semmle/go/frameworks/WebSocket.qll b/ql/src/semmle/go/frameworks/WebSocket.qll index 0919ae2aafa..fc2278d785c 100644 --- a/ql/src/semmle/go/frameworks/WebSocket.qll +++ b/ql/src/semmle/go/frameworks/WebSocket.qll @@ -271,4 +271,28 @@ module WebSocketReader { override FunctionOutput getAnOutput() { result.isResult(1) } } + + /** + * The `ServerWebSocket.MessageReceive` method of the `github.com/revel/revel` package. + */ + private class RevelServerWebSocketMessageReceive extends Range, Method { + RevelServerWebSocketMessageReceive() { + // func MessageReceive(v interface{}) error + this.hasQualifiedName(Revel::packagePath(), "ServerWebSocket", "MessageReceive") + } + + override FunctionOutput getAnOutput() { result.isParameter(0) } + } + + /** + * The `ServerWebSocket.MessageReceiveJSON` method of the `github.com/revel/revel` package. + */ + private class RevelServerWebSocketMessageReceiveJSON extends Range, Method { + RevelServerWebSocketMessageReceiveJSON() { + // func MessageReceiveJSON(v interface{}) error + this.hasQualifiedName(Revel::packagePath(), "ServerWebSocket", "MessageReceiveJSON") + } + + override FunctionOutput getAnOutput() { result.isParameter(0) } + } } diff --git a/ql/test/library-tests/semmle/go/frameworks/Revel/Revel.go b/ql/test/library-tests/semmle/go/frameworks/Revel/Revel.go new file mode 100644 index 00000000000..b067d0238e5 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Revel/Revel.go @@ -0,0 +1,111 @@ +package main + +//go:generate depstubber -vendor github.com/revel/revel Controller,Params,Request,Router HTTP_QUERY + +import ( + "io/ioutil" + "mime/multipart" + "net/url" + + "github.com/revel/revel" +) + +func main() {} + +type myAppController struct { + *revel.Controller + OtherStuff string +} + +type person struct { + Name string `form:"name"` + Address string `form:"address"` +} + +func useString(val string) {} + +func useFiles(val *multipart.FileHeader) {} + +func useJSON(val []byte) {} + +func useURLValues(v url.Values) { + useString(v["key"][0]) + useString(v.Get("key")) +} + +func usePerson(p person) {} + +func (c myAppController) accessingParamsDirectlyIsUnsafe() { + useString(c.Params.Get("key")) // NOT OK + useURLValues(c.Params.Values) // NOT OK + + val4 := "" + c.Params.Bind(&val4, "key") // NOT OK + useString(val4) + + useString(c.Request.FormValue("key")) // NOT OK +} + +func (c myAppController) accessingFixedIsSafe(mainRouter *revel.Router) { + useURLValues(c.Params.Fixed) // OK + useString(mainRouter.Route(c.Request).FixedParams[0]) // OK +} + +func (c myAppController) accessingRouteIsUnsafe(mainRouter *revel.Router) { + useURLValues(c.Params.Route) // NOT OK + useURLValues(mainRouter.Route(c.Request).Params) // NOT OK +} + +func (c myAppController) accessingParamsQueryIsUnsafe() { + useURLValues(c.Params.Query) // NOT OK +} + +func (c myAppController) accessingParamsFormIsUnsafe() { + useURLValues(c.Params.Form) // NOT OK + useString(c.Request.PostFormValue("key")) // NOT OK +} + +func (c myAppController) accessingParamsFilesIsUnsafe() { + useFiles(c.Params.Files["key"][0]) // NOT OK +} + +func (c myAppController) accessingParamsJSONIsUnsafe() { + useJSON(c.Params.JSON) // NOT OK + + var val2 map[string]interface{} + c.Params.BindJSON(&val2) // NOT OK + useString(val2["name"].(string)) +} + +func accessingRequestDirectlyIsUnsafe(c *revel.Controller) { + useURLValues(c.Request.GetQuery()) // NOT OK + useURLValues(c.Request.Form) // NOT OK + useURLValues(c.Request.MultipartForm.Value) // NOT OK + + form, _ := c.Request.GetForm() // NOT OK + useURLValues(form) + + smp1, _ := c.Request.GetMultipartForm() // NOT OK + useURLValues(smp1.GetValues()) + + smp2, _ := c.Request.GetMultipartForm() // NOT OK + useFiles(smp2.GetFiles()["key"][0]) + + useFiles(c.Request.MultipartForm.File["key"][0]) // NOT OK + + json, _ := ioutil.ReadAll(c.Request.GetBody()) // NOT OK + useJSON(json) +} + +func accessingServerRequest(c *revel.Controller) { + query, _ := c.Request.In.Get(revel.HTTP_QUERY) // NOT OK + useURLValues(query.(url.Values)) + + var message string + c.Request.WebSocket.MessageReceive(&message) // NOT OK + useString(message) + + var p person + c.Request.WebSocket.MessageReceiveJSON(&p) // NOT OK + usePerson(p) +} diff --git a/ql/test/library-tests/semmle/go/frameworks/Revel/TaintFlows.expected b/ql/test/library-tests/semmle/go/frameworks/Revel/TaintFlows.expected new file mode 100644 index 00000000000..1b58fbfb755 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Revel/TaintFlows.expected @@ -0,0 +1,34 @@ +| Revel.go:39:12:39:19 | selection of Params : pointer type | Revel.go:39:12:39:30 | call to Get | 39 | +| Revel.go:40:15:40:22 | selection of Params : pointer type | Revel.go:32:12:32:22 | index expression | 40 | +| Revel.go:40:15:40:22 | selection of Params : pointer type | Revel.go:33:12:33:23 | call to Get | 40 | +| Revel.go:43:2:43:9 | selection of Params : pointer type | Revel.go:44:12:44:15 | val4 | 43 | +| Revel.go:46:12:46:37 | call to FormValue | Revel.go:46:12:46:37 | call to FormValue | 46 | +| Revel.go:55:15:55:22 | selection of Params : pointer type | Revel.go:32:12:32:22 | index expression | 55 | +| Revel.go:55:15:55:22 | selection of Params : pointer type | Revel.go:33:12:33:23 | call to Get | 55 | +| Revel.go:56:15:56:48 | selection of Params : map type | Revel.go:32:12:32:22 | index expression | 56 | +| Revel.go:56:15:56:48 | selection of Params : map type | Revel.go:33:12:33:23 | call to Get | 56 | +| Revel.go:60:15:60:22 | selection of Params : pointer type | Revel.go:32:12:32:22 | index expression | 60 | +| Revel.go:60:15:60:22 | selection of Params : pointer type | Revel.go:33:12:33:23 | call to Get | 60 | +| Revel.go:64:15:64:22 | selection of Params : pointer type | Revel.go:32:12:32:22 | index expression | 64 | +| Revel.go:64:15:64:22 | selection of Params : pointer type | Revel.go:33:12:33:23 | call to Get | 64 | +| Revel.go:65:12:65:41 | call to PostFormValue | Revel.go:65:12:65:41 | call to PostFormValue | 65 | +| Revel.go:69:11:69:18 | selection of Params : pointer type | Revel.go:69:11:69:34 | index expression | 69 | +| Revel.go:73:10:73:17 | selection of Params : pointer type | Revel.go:73:10:73:22 | selection of JSON | 73 | +| Revel.go:76:2:76:9 | selection of Params : pointer type | Revel.go:77:12:77:32 | type assertion | 76 | +| Revel.go:81:15:81:34 | call to GetQuery : Values | Revel.go:32:12:32:22 | index expression | 81 | +| Revel.go:81:15:81:34 | call to GetQuery : Values | Revel.go:33:12:33:23 | call to Get | 81 | +| Revel.go:82:15:82:28 | selection of Form : Values | Revel.go:32:12:32:22 | index expression | 82 | +| Revel.go:82:15:82:28 | selection of Form : Values | Revel.go:33:12:33:23 | call to Get | 82 | +| Revel.go:83:15:83:37 | selection of MultipartForm : pointer type | Revel.go:32:12:32:22 | index expression | 83 | +| Revel.go:83:15:83:37 | selection of MultipartForm : pointer type | Revel.go:33:12:33:23 | call to Get | 83 | +| Revel.go:85:13:85:31 | call to GetForm : tuple type | Revel.go:32:12:32:22 | index expression | 85 | +| Revel.go:85:13:85:31 | call to GetForm : tuple type | Revel.go:33:12:33:23 | call to Get | 85 | +| Revel.go:88:13:88:40 | call to GetMultipartForm : tuple type | Revel.go:32:12:32:22 | index expression | 88 | +| Revel.go:88:13:88:40 | call to GetMultipartForm : tuple type | Revel.go:33:12:33:23 | call to Get | 88 | +| Revel.go:91:13:91:40 | call to GetMultipartForm : tuple type | Revel.go:92:11:92:35 | index expression | 91 | +| Revel.go:94:11:94:33 | selection of MultipartForm : pointer type | Revel.go:94:11:94:48 | index expression | 94 | +| Revel.go:96:28:96:46 | call to GetBody : Reader | Revel.go:97:10:97:13 | json | 96 | +| Revel.go:101:14:101:25 | selection of In : ServerRequest | Revel.go:32:12:32:22 | index expression | 101 | +| Revel.go:101:14:101:25 | selection of In : ServerRequest | Revel.go:33:12:33:23 | call to Get | 101 | +| Revel.go:105:37:105:44 | &... : pointer type | Revel.go:106:12:106:18 | message | 105 | +| Revel.go:109:41:109:42 | &... : pointer type | Revel.go:110:12:110:12 | p | 109 | diff --git a/ql/test/library-tests/semmle/go/frameworks/Revel/TaintFlows.ql b/ql/test/library-tests/semmle/go/frameworks/Revel/TaintFlows.ql new file mode 100644 index 00000000000..e41767f0a97 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Revel/TaintFlows.ql @@ -0,0 +1,19 @@ +import go + +class SinkFunction extends Function { + SinkFunction() { this.getName() = ["useFiles", "useJSON", "usePerson", "useString"] } +} + +class TestConfig extends TaintTracking::Configuration { + TestConfig() { this = "testconfig" } + + override predicate isSource(DataFlow::Node source) { source instanceof UntrustedFlowSource } + + override predicate isSink(DataFlow::Node sink) { + sink = any(SinkFunction f).getACall().getAnArgument() + } +} + +from TaintTracking::Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink, int i +where config.hasFlowPath(source, sink) and source.hasLocationInfo(_, i, _, _, _) +select source, sink, i order by i diff --git a/ql/test/library-tests/semmle/go/frameworks/Revel/go.mod b/ql/test/library-tests/semmle/go/frameworks/Revel/go.mod new file mode 100644 index 00000000000..a0968095036 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Revel/go.mod @@ -0,0 +1,20 @@ +module codeql-go-tests/frameworks/Revel + +go 1.14 + +require ( + github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/github/depstubber v0.0.0-20200910105848-4f6b1e61222c // indirect + github.com/go-stack/stack v1.8.0 // indirect + github.com/inconshreveable/log15 v0.0.0-20200109203555-b30bc20e4fd1 // indirect + github.com/mattn/go-colorable v0.1.7 // indirect + github.com/revel/config v1.0.0 // indirect + github.com/revel/log15 v2.11.20+incompatible // indirect + github.com/revel/pathtree v0.0.0-20140121041023-41257a1839e9 // indirect + github.com/revel/revel v1.0.0 + github.com/twinj/uuid v1.0.0 // indirect + github.com/xeonx/timeago v1.0.0-rc4 // indirect + golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect + gopkg.in/stack.v0 v0.0.0-20141108040640-9b43fcefddd0 // indirect +) diff --git a/ql/test/library-tests/semmle/go/frameworks/Revel/vendor/github.com/revel/revel/stub.go b/ql/test/library-tests/semmle/go/frameworks/Revel/vendor/github.com/revel/revel/stub.go new file mode 100644 index 00000000000..c2bfe8c15ef --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Revel/vendor/github.com/revel/revel/stub.go @@ -0,0 +1,705 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for github.com/revel/revel, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: github.com/revel/revel (exports: Controller,Params,Request,Router; functions: HTTP_QUERY) + +// Package revel is a stub of github.com/revel/revel, generated by depstubber. +package revel + +import ( + context "context" + io "io" + multipart "mime/multipart" + http "net/http" + url "net/url" + os "os" + reflect "reflect" + regexp "regexp" + time "time" +) + +type AcceptLanguage struct { + Language string + Quality float32 +} + +type AcceptLanguages []AcceptLanguage + +func (_ AcceptLanguages) Len() int { + return 0 +} + +func (_ AcceptLanguages) Less(_ int, _ int) bool { + return false +} + +func (_ AcceptLanguages) String() string { + return "" +} + +func (_ AcceptLanguages) Swap(_ int, _ int) {} + +type ActionDefinition struct { + Host string + Method string + URL string + Action string + Star bool + Args map[string]string +} + +func (_ *ActionDefinition) String() string { + return "" +} + +type ContentDisposition string + +type Controller struct { + Name string + Type *ControllerType + MethodName string + MethodType *MethodType + AppController interface{} + Action string + ClientIP string + Request *Request + Response *Response + Result Result + Flash Flash + Session interface{} + Params *Params + Args map[string]interface{} + ViewArgs map[string]interface{} + Validation *Validation + Log interface{} +} + +func (_ *Controller) Destroy() {} + +func (_ *Controller) FlashParams() {} + +func (_ *Controller) Forbidden(_ string, _ ...interface{}) Result { + return nil +} + +func (_ *Controller) Message(_ string, _ ...interface{}) string { + return "" +} + +func (_ *Controller) NotFound(_ string, _ ...interface{}) Result { + return nil +} + +func (_ *Controller) Redirect(_ interface{}, _ ...interface{}) Result { + return nil +} + +func (_ *Controller) Render(_ ...interface{}) Result { + return nil +} + +func (_ *Controller) RenderBinary(_ io.Reader, _ string, _ ContentDisposition, _ time.Time) Result { + return nil +} + +func (_ *Controller) RenderError(_ error) Result { + return nil +} + +func (_ *Controller) RenderFile(_ *os.File, _ ContentDisposition) Result { + return nil +} + +func (_ *Controller) RenderFileName(_ string, _ ContentDisposition) Result { + return nil +} + +func (_ *Controller) RenderHTML(_ string) Result { + return nil +} + +func (_ *Controller) RenderJSON(_ interface{}) Result { + return nil +} + +func (_ *Controller) RenderJSONP(_ string, _ interface{}) Result { + return nil +} + +func (_ *Controller) RenderTemplate(_ string) Result { + return nil +} + +func (_ *Controller) RenderText(_ string, _ ...interface{}) Result { + return nil +} + +func (_ *Controller) RenderXML(_ interface{}) Result { + return nil +} + +func (_ *Controller) SetAction(_ string, _ string) error { + return nil +} + +func (_ *Controller) SetController(_ ServerContext) {} + +func (_ *Controller) SetCookie(_ *http.Cookie) {} + +func (_ *Controller) SetTypeAction(_ string, _ string, _ *ControllerType) error { + return nil +} + +func (_ *Controller) Stats() map[string]interface{} { + return nil +} + +func (_ *Controller) TemplateOutput(_ string) ([]byte, error) { + return nil, nil +} + +func (_ *Controller) Todo() Result { + return nil +} + +type ControllerFieldPath struct { + IsPointer bool + FieldIndexPath []int + FunctionCall reflect.Value +} + +func (_ *ControllerFieldPath) Invoke(_ reflect.Value, _ []reflect.Value) []reflect.Value { + return nil +} + +type ControllerType struct { + Namespace string + ModuleSource *Module + Type reflect.Type + Methods []*MethodType + ControllerIndexes [][]int + ControllerEvents *ControllerTypeEvents +} + +func (_ *ControllerType) Method(_ string) *MethodType { + return nil +} + +func (_ *ControllerType) Name() string { + return "" +} + +func (_ *ControllerType) ShortName() string { + return "" +} + +type ControllerTypeEvents struct { + Before []*ControllerFieldPath + After []*ControllerFieldPath + Finally []*ControllerFieldPath + Panic []*ControllerFieldPath +} + +type Error struct { + SourceType string + Title string + Path string + Description string + Line int + Column int + SourceLines []string + Stack string + MetaError string + Link string +} + +func (_ *Error) ContextSource() []SourceLine { + return nil +} + +func (_ *Error) Error() string { + return "" +} + +func (_ *Error) SetLink(_ string) {} + +type Flash struct { + Data map[string]string + Out map[string]string +} + +func (_ Flash) Error(_ string, _ ...interface{}) {} + +func (_ Flash) Success(_ string, _ ...interface{}) {} + +var HTTP_QUERY int = 0 + +type MethodArg struct { + Name string + Type reflect.Type +} + +type MethodType struct { + Name string + Args []*MethodArg + RenderArgNames map[int][]string + Index int +} + +type Module struct { + Name string + ImportPath string + Path string + ControllerTypeList []*ControllerType + Log interface{} +} + +func (_ *Module) AddController(_ *ControllerType) {} + +func (_ *Module) ControllerByName(_ string, _ string) *ControllerType { + return nil +} + +func (_ *Module) Namespace() string { + return "" +} + +type MultipartForm struct { + File map[string][]*multipart.FileHeader + Value url.Values +} + +type OutResponse struct { + Server ServerResponse +} + +func (_ *OutResponse) Destroy() {} + +func (_ *OutResponse) Header() *RevelHeader { + return nil +} + +func (_ *OutResponse) Write(_ []byte) (int, error) { + return 0, nil +} + +type Params struct { + Values url.Values + Fixed url.Values + Route url.Values + Query url.Values + Form url.Values + Files map[string][]*multipart.FileHeader + JSON []byte +} + +func (_ Params) Add(_ string, _ string) {} + +func (_ Params) Del(_ string) {} + +func (_ Params) Encode() string { + return "" +} + +func (_ Params) Get(_ string) string { + return "" +} + +func (_ Params) Set(_ string, _ string) {} + +func (_ *Params) Bind(_ interface{}, _ string) {} + +func (_ *Params) BindJSON(_ interface{}) error { + return nil +} + +type Request struct { + In ServerRequest + Header *RevelHeader + ContentType string + Format string + AcceptLanguages AcceptLanguages + Locale string + WebSocket ServerWebSocket + Method string + RemoteAddr string + Host string + URL *url.URL + Form url.Values + MultipartForm *MultipartForm +} + +func (_ *Request) Args() map[string]interface{} { + return nil +} + +func (_ *Request) Context() context.Context { + return nil +} + +func (_ *Request) Cookie(_ string) (ServerCookie, error) { + return nil, nil +} + +func (_ *Request) Destroy() {} + +func (_ *Request) FormValue(_ string) string { + return "" +} + +func (_ *Request) GetBody() io.Reader { + return nil +} + +func (_ *Request) GetForm() (url.Values, error) { + return nil, nil +} + +func (_ *Request) GetHttpHeader(_ string) string { + return "" +} + +func (_ *Request) GetMultipartForm() (ServerMultipartForm, error) { + return nil, nil +} + +func (_ *Request) GetPath() string { + return "" +} + +func (_ *Request) GetQuery() url.Values { + return nil +} + +func (_ *Request) GetRequestURI() string { + return "" +} + +func (_ *Request) GetValue(_ int) interface{} { + return nil +} + +func (_ *Request) MultipartReader() (*multipart.Reader, error) { + return nil, nil +} + +func (_ *Request) ParseForm() error { + return nil +} + +func (_ *Request) ParseMultipartForm(_ int64) error { + return nil +} + +func (_ *Request) PostFormValue(_ string) string { + return "" +} + +func (_ *Request) Referer() string { + return "" +} + +func (_ *Request) SetRequest(_ ServerRequest) {} + +func (_ *Request) UserAgent() string { + return "" +} + +type Response struct { + Status int + ContentType string + Out OutResponse +} + +func (_ *Response) Destroy() {} + +func (_ *Response) GetStreamWriter() StreamWriter { + return nil +} + +func (_ *Response) GetWriter() io.Writer { + return nil +} + +func (_ *Response) SetResponse(_ ServerResponse) {} + +func (_ *Response) SetStatus(_ int) {} + +func (_ *Response) SetWriter(_ io.Writer) bool { + return false +} + +func (_ *Response) WriteHeader(_ int, _ string) {} + +type Result interface { + Apply(_ *Request, _ *Response) +} + +type RevelHeader struct { + Server ServerHeader +} + +func (_ *RevelHeader) Add(_ string, _ string) {} + +func (_ *RevelHeader) Destroy() {} + +func (_ *RevelHeader) Get(_ string) string { + return "" +} + +func (_ *RevelHeader) GetAll(_ string) []string { + return nil +} + +func (_ *RevelHeader) Set(_ string, _ string) {} + +func (_ *RevelHeader) SetCookie(_ string) {} + +func (_ *RevelHeader) SetStatus(_ int) {} + +type Route struct { + ModuleSource *Module + Method string + Path string + Action string + ControllerNamespace string + ControllerName string + MethodName string + FixedParams []string + TreePath string + TypeOfController *ControllerType +} + +func (_ *Route) ActionPath() string { + return "" +} + +type RouteMatch struct { + Action string + ControllerName string + MethodName string + FixedParams []string + Params map[string][]string + TypeOfController *ControllerType + ModuleSource *Module +} + +type Router struct { + Routes []*Route + Tree interface{} + Module string +} + +func (_ *Router) Refresh() *Error { + return nil +} + +func (_ *Router) Reverse(_ string, _ map[string]string) *ActionDefinition { + return nil +} + +func (_ *Router) ReverseError(_ string, _ map[string]string, _ *Request) (*ActionDefinition, error) { + return nil, nil +} + +func (_ *Router) Route(_ *Request) *RouteMatch { + return nil +} + +type ServerContext interface { + GetRequest() ServerRequest + GetResponse() ServerResponse +} + +type ServerCookie interface { + GetValue() string +} + +type ServerHeader interface { + Add(_ string, _ string) + Del(_ string) + Get(_ string) []string + GetCookie(_ string) (ServerCookie, error) + GetKeys() []string + Set(_ string, _ string) + SetCookie(_ string) + SetStatus(_ int) +} + +type ServerMultipartForm interface { + GetFiles() map[string][]*multipart.FileHeader + GetValues() url.Values + RemoveAll() error +} + +type ServerRequest interface { + Get(_ int) (interface{}, error) + GetRaw() interface{} + Set(_ int, _ interface{}) bool +} + +type ServerResponse interface { + Get(_ int) (interface{}, error) + GetRaw() interface{} + Set(_ int, _ interface{}) bool +} + +type ServerWebSocket interface { + Get(_ int) (interface{}, error) + GetRaw() interface{} + MessageReceive(_ interface{}) error + MessageReceiveJSON(_ interface{}) error + MessageSend(_ interface{}) error + MessageSendJSON(_ interface{}) error + Set(_ int, _ interface{}) bool +} + +type SourceLine struct { + Source string + Line int + IsError bool +} + +type StreamWriter interface { + WriteStream(_ string, _ int64, _ time.Time, _ io.Reader) error +} + +type Validation struct { + Errors []*ValidationError + Request *Request + Translator func(string, string, ...interface{}) string +} + +func (_ *Validation) Check(_ interface{}, _ ...Validator) *ValidationResult { + return nil +} + +func (_ *Validation) Clear() {} + +func (_ *Validation) Domain(_ string) *ValidationResult { + return nil +} + +func (_ *Validation) Email(_ string) *ValidationResult { + return nil +} + +func (_ *Validation) Error(_ string, _ ...interface{}) *ValidationResult { + return nil +} + +func (_ *Validation) ErrorKey(_ string, _ ...interface{}) *ValidationResult { + return nil +} + +func (_ *Validation) ErrorMap() map[string]*ValidationError { + return nil +} + +func (_ *Validation) FilePath(_ string, _ int) *ValidationResult { + return nil +} + +func (_ *Validation) HasErrors() bool { + return false +} + +func (_ *Validation) IPAddr(_ string, _ ...int) *ValidationResult { + return nil +} + +func (_ *Validation) Keep() {} + +func (_ *Validation) Length(_ interface{}, _ int) *ValidationResult { + return nil +} + +func (_ *Validation) MacAddr(_ string) *ValidationResult { + return nil +} + +func (_ *Validation) Match(_ string, _ *regexp.Regexp) *ValidationResult { + return nil +} + +func (_ *Validation) Max(_ int, _ int) *ValidationResult { + return nil +} + +func (_ *Validation) MaxFloat(_ float64, _ float64) *ValidationResult { + return nil +} + +func (_ *Validation) MaxSize(_ interface{}, _ int) *ValidationResult { + return nil +} + +func (_ *Validation) Min(_ int, _ int) *ValidationResult { + return nil +} + +func (_ *Validation) MinFloat(_ float64, _ float64) *ValidationResult { + return nil +} + +func (_ *Validation) MinSize(_ interface{}, _ int) *ValidationResult { + return nil +} + +func (_ *Validation) PureText(_ string, _ int) *ValidationResult { + return nil +} + +func (_ *Validation) Range(_ int, _ int, _ int) *ValidationResult { + return nil +} + +func (_ *Validation) RangeFloat(_ float64, _ float64, _ float64) *ValidationResult { + return nil +} + +func (_ *Validation) Required(_ interface{}) *ValidationResult { + return nil +} + +func (_ *Validation) URL(_ string) *ValidationResult { + return nil +} + +func (_ *Validation) ValidationResult(_ bool) *ValidationResult { + return nil +} + +type ValidationError struct { + Message string + Key string +} + +func (_ *ValidationError) String() string { + return "" +} + +type ValidationResult struct { + Error *ValidationError + Ok bool + Locale string + Translator func(string, string, ...interface{}) string +} + +func (_ *ValidationResult) Key(_ string) *ValidationResult { + return nil +} + +func (_ *ValidationResult) Message(_ string, _ ...interface{}) *ValidationResult { + return nil +} + +func (_ *ValidationResult) MessageKey(_ string, _ ...interface{}) *ValidationResult { + return nil +} + +type Validator interface { + DefaultMessage() string + IsSatisfied(_ interface{}) bool +} diff --git a/ql/test/library-tests/semmle/go/frameworks/Revel/vendor/modules.txt b/ql/test/library-tests/semmle/go/frameworks/Revel/vendor/modules.txt new file mode 100644 index 00000000000..b42e9ce651d --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Revel/vendor/modules.txt @@ -0,0 +1,42 @@ +# github.com/fsnotify/fsnotify v1.4.9 +## explicit +github.com/fsnotify/fsnotify +# github.com/github/depstubber v0.0.0-20200910105848-4f6b1e61222c +## explicit +github.com/github/depstubber +# github.com/go-stack/stack v1.8.0 +## explicit +github.com/go-stack/stack +# github.com/inconshreveable/log15 v0.0.0-20200109203555-b30bc20e4fd1 +## explicit +github.com/inconshreveable/log15 +# github.com/mattn/go-colorable v0.1.7 +## explicit +github.com/mattn/go-colorable +# github.com/revel/config v1.0.0 +## explicit +github.com/revel/config +# github.com/revel/log15 v2.11.20+incompatible +## explicit +github.com/revel/log15 +# github.com/revel/pathtree v0.0.0-20140121041023-41257a1839e9 +## explicit +github.com/revel/pathtree +# github.com/revel/revel v1.0.0 +## explicit +github.com/revel/revel +# github.com/twinj/uuid v1.0.0 +## explicit +github.com/twinj/uuid +# github.com/xeonx/timeago v1.0.0-rc4 +## explicit +github.com/xeonx/timeago +# golang.org/x/net v0.0.0-20200904194848-62affa334b73 +## explicit +golang.org/x/net +# gopkg.in/natefinch/lumberjack.v2 v2.0.0 +## explicit +gopkg.in/natefinch/lumberjack.v2 +# gopkg.in/stack.v0 v0.0.0-20141108040640-9b43fcefddd0 +## explicit +gopkg.in/stack.v0