Add web framework: clevergo

This commit is contained in:
Slavomir
2020-12-20 23:34:49 +01:00
committed by Chris Smowton
parent 7bf5abf6b0
commit 6d9b7d3240
14 changed files with 936 additions and 1 deletions

View File

@@ -34,7 +34,7 @@ import semmle.go.dataflow.TaintTracking2
import semmle.go.frameworks.Beego
import semmle.go.frameworks.BeegoOrm
import semmle.go.frameworks.Chi
import semmle.go.frameworks.Couchbase
import semmle.go.frameworks.Echo
import semmle.go.frameworks.ElazarlGoproxy
import semmle.go.frameworks.Email

View File

@@ -0,0 +1,141 @@
/**
* TODO: Doc about this file.
*/
import DataFlow::PathGraph
import go
/**
* TODO: Doc about this module.
*/
private module CleverGo {
/** Gets the package path. */
bindingset[result]
string packagePath() { result = ["clevergo.tech/clevergo", "github.com/clevergo/clevergo"] }
/**
* Provides models of untrusted flow sources.
*/
private class UntrustedSources extends UntrustedFlowSource::Range {
UntrustedSources() {
// Methods on types of package: clevergo.tech/clevergo@v0.5.2
exists(string methodName, Method mtd, FunctionOutput outp |
this = outp.getExitNode(mtd.getACall())
|
// Receiver: Context
mtd.hasQualifiedName(packagePath(), "Context", methodName) and
(
// Method: func (*Context).BasicAuth() (username string, password string, ok bool)
methodName = "BasicAuth" and
outp.isResult([0, 1])
or
// Method: func (*Context).Decode(v interface{}) (err error)
methodName = "Decode" and
outp.isParameter(0)
or
// Method: func (*Context).DefaultQuery(key string, defaultVlue string) string
methodName = "DefaultQuery" and
outp.isResult()
or
// Method: func (*Context).FormValue(key string) string
methodName = "FormValue" and
outp.isResult()
or
// Method: func (*Context).GetHeader(name string) string
methodName = "GetHeader" and
outp.isResult()
or
// Method: func (*Context).PostFormValue(key string) string
methodName = "PostFormValue" and
outp.isResult()
or
// Method: func (*Context).QueryParam(key string) string
methodName = "QueryParam" and
outp.isResult()
or
// Method: func (*Context).QueryString() string
methodName = "QueryString" and
outp.isResult()
)
or
// Receiver: Params
mtd.hasQualifiedName(packagePath(), "Params", methodName) and
(
// Method: func (Params).String(name string) string
methodName = "String" and
outp.isResult()
)
)
or
// Structs of package: clevergo.tech/clevergo@v0.5.2
exists(DataFlow::Field fld |
// Struct: Context
fld.hasQualifiedName(packagePath(), "Context", "Params")
or
// Struct: Param
fld.hasQualifiedName(packagePath(), "Param", ["Key", "Value"])
|
this = fld.getARead()
)
or
// Types of package: clevergo.tech/clevergo@v0.5.2
exists(DataFlow::ReadNode read, ValueEntity v |
v.getType().hasQualifiedName(packagePath(), "Params")
|
read.reads(v) and
this = read
)
}
}
// Models taint-tracking through functions.
private class TaintTrackingFunctionModels extends TaintTracking::FunctionModel {
FunctionInput inp;
FunctionOutput out;
TaintTrackingFunctionModels() {
// Taint-tracking models for package: clevergo.tech/clevergo@v0.5.2
(
// signature: func CleanPath(p string) string
hasQualifiedName(packagePath(), "CleanPath") and
(
inp.isParameter(0) and
out.isResult()
)
)
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = inp and output = out
}
}
// Models taint-tracking through method calls.
private class TaintTrackingMethodModels extends TaintTracking::FunctionModel, Method {
FunctionInput inp;
FunctionOutput out;
TaintTrackingMethodModels() {
// Taint-tracking models for package: clevergo.tech/clevergo@v0.5.2
(
// signature: func (Decoder).Decode(req *net/http.Request, v interface{}) error
implements(packagePath(), "Decoder", "Decode") and
(
inp.isParameter(0) and
out.isParameter(1)
)
or
// signature: func (Renderer).Render(w io.Writer, name string, data interface{}, c *Context) error
implements(packagePath(), "Renderer", "Render") and
(
inp.isParameter(2) and
out.isParameter(0)
)
)
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = inp and output = out
}
}
}

View File

@@ -0,0 +1,59 @@
// Code generated by https://github.com/gagliardetto. DO NOT EDIT.
package main
import (
"clevergo.tech/clevergo"
"io"
"net/http"
)
func main() {}
func sink(v interface{}) {}
func link(from interface{}, into interface{}) {}
func source() interface{} {
return nil
}
// Package clevergo.tech/clevergo@v0.5.2
func ClevergoTechClevergov052() {
// Taint-tracking through functions.
{
// func CleanPath(p string) string
{
fromString599 := source().(string)
intoString409 := clevergo.CleanPath(fromString599)
sink(intoString409) // $SinkingSource
}
}
// Taint-tracking through interface method calls.
{
// Taint-tracking through method calls on clevergo.tech/clevergo.Decoder interface.
{
// func (Decoder).Decode(req *net/http.Request, v interface{}) error
{
fromRequest246 := source().(*http.Request)
var intoInterface898 interface{}
var mediumObjCQL clevergo.Decoder
mediumObjCQL.Decode(fromRequest246, intoInterface898)
sink(intoInterface898) // $SinkingSource
}
}
// Taint-tracking through method calls on clevergo.tech/clevergo.Renderer interface.
{
// func (Renderer).Render(w io.Writer, name string, data interface{}, c *Context) error
{
fromInterface598 := source().(interface{})
var intoWriter631 io.Writer
var mediumObjCQL clevergo.Renderer
mediumObjCQL.Render(intoWriter631, "", fromInterface598, nil)
sink(intoWriter631) // $SinkingSource
}
}
}
}
//go:generate depstubber -vendor clevergo.tech/clevergo Context,Decoder,Renderer CleanPath
//go:generate depstubber -write_module_txt

View File

@@ -0,0 +1,29 @@
import go
import TestUtilities.InlineExpectationsTest
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "test-configuration" }
override predicate isSource(DataFlow::Node source) {
exists(Function fn | fn.hasQualifiedName(_, "source") | source = fn.getACall().getResult())
}
override predicate isSink(DataFlow::Node sink) {
exists(Function fn | fn.hasQualifiedName(_, "sink") | sink = fn.getACall().getAnArgument())
}
}
class TaintTrackingTest extends InlineExpectationsTest {
TaintTrackingTest() { this = "TaintTrackingTest" }
override string getARelevantTag() { result = "SinkingSource" }
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
tag = "SinkingSource" and
exists(DataFlow::Node sink | any(Configuration c).hasFlow(_, sink) |
element = sink.toString() and
value = "" and
sink.hasLocationInfo(file, line, _, _, _)
)
}
}

View File

@@ -0,0 +1,8 @@
module example.com/hello/world
go 1.15
require (
clevergo.tech/clevergo v0.5.2
github.com/github/depstubber v0.0.0-20201214172518-12c3da4b7c9d // indirect
)

View File

@@ -0,0 +1,282 @@
// Code generated by depstubber. DO NOT EDIT.
// This is a simple stub for clevergo.tech/clevergo, strictly for use in testing.
// See the LICENSE file for information about the licensing of the original library.
// Source: clevergo.tech/clevergo (exports: Context,Decoder,Renderer; functions: CleanPath)
// Package clevergo is a stub of clevergo.tech/clevergo, generated by depstubber.
package clevergo
import (
context "context"
io "io"
http "net/http"
url "net/url"
time "time"
)
func CleanPath(_ string) string {
return ""
}
type Context struct {
Params Params
Route *Route
Request *http.Request
Response http.ResponseWriter
}
func (_ *Context) BasicAuth() (string, string, bool) {
return "", "", false
}
func (_ *Context) Blob(_ int, _ string, _ []byte) error {
return nil
}
func (_ *Context) Context() context.Context {
return nil
}
func (_ *Context) Cookie(_ string) (*http.Cookie, error) {
return nil, nil
}
func (_ *Context) Cookies() []*http.Cookie {
return nil
}
func (_ *Context) Decode(_ interface{}) error {
return nil
}
func (_ *Context) DefaultQuery(_ string, _ string) string {
return ""
}
func (_ *Context) Emit(_ int, _ string, _ string) error {
return nil
}
func (_ *Context) Error(_ int, _ string) error {
return nil
}
func (_ *Context) FormValue(_ string) string {
return ""
}
func (_ *Context) GetHeader(_ string) string {
return ""
}
func (_ *Context) HTML(_ int, _ string) error {
return nil
}
func (_ *Context) HTMLBlob(_ int, _ []byte) error {
return nil
}
func (_ *Context) Host() string {
return ""
}
func (_ *Context) IsAJAX() bool {
return false
}
func (_ *Context) IsDelete() bool {
return false
}
func (_ *Context) IsGet() bool {
return false
}
func (_ *Context) IsMethod(_ string) bool {
return false
}
func (_ *Context) IsOptions() bool {
return false
}
func (_ *Context) IsPatch() bool {
return false
}
func (_ *Context) IsPost() bool {
return false
}
func (_ *Context) IsPut() bool {
return false
}
func (_ *Context) JSON(_ int, _ interface{}) error {
return nil
}
func (_ *Context) JSONBlob(_ int, _ []byte) error {
return nil
}
func (_ *Context) JSONP(_ int, _ interface{}) error {
return nil
}
func (_ *Context) JSONPBlob(_ int, _ []byte) error {
return nil
}
func (_ *Context) JSONPCallback(_ int, _ string, _ interface{}) error {
return nil
}
func (_ *Context) JSONPCallbackBlob(_ int, _ string, _ []byte) error {
return nil
}
func (_ *Context) Logger() interface{} {
return nil
}
func (_ *Context) NotFound() error {
return nil
}
func (_ *Context) PostFormValue(_ string) string {
return ""
}
func (_ *Context) QueryParam(_ string) string {
return ""
}
func (_ *Context) QueryParams() url.Values {
return nil
}
func (_ *Context) QueryString() string {
return ""
}
func (_ *Context) Redirect(_ int, _ string) error {
return nil
}
func (_ *Context) Render(_ int, _ string, _ interface{}) error {
return nil
}
func (_ *Context) RouteURL(_ string, _ ...string) (*url.URL, error) {
return nil, nil
}
func (_ *Context) SendFile(_ string, _ io.Reader) error {
return nil
}
func (_ *Context) ServeContent(_ string, _ time.Time, _ io.ReadSeeker) error {
return nil
}
func (_ *Context) ServeFile(_ string) error {
return nil
}
func (_ *Context) SetContentType(_ string) {}
func (_ *Context) SetContentTypeHTML() {}
func (_ *Context) SetContentTypeJSON() {}
func (_ *Context) SetContentTypeText() {}
func (_ *Context) SetContentTypeXML() {}
func (_ *Context) SetCookie(_ *http.Cookie) {}
func (_ *Context) SetHeader(_ string, _ string) {}
func (_ *Context) String(_ int, _ string) error {
return nil
}
func (_ *Context) StringBlob(_ int, _ []byte) error {
return nil
}
func (_ *Context) Stringf(_ int, _ string, _ ...interface{}) error {
return nil
}
func (_ *Context) Value(_ interface{}) interface{} {
return nil
}
func (_ *Context) WithValue(_ interface{}, _ interface{}) {}
func (_ *Context) Write(_ []byte) (int, error) {
return 0, nil
}
func (_ *Context) WriteHeader(_ int) {}
func (_ *Context) WriteString(_ string) (int, error) {
return 0, nil
}
func (_ *Context) XML(_ int, _ interface{}) error {
return nil
}
func (_ *Context) XMLBlob(_ int, _ []byte) error {
return nil
}
type Decoder interface {
Decode(_ *http.Request, _ interface{}) error
}
type Param struct {
Key string
Value string
}
type Params []Param
func (_ Params) Bool(_ string) (bool, error) {
return false, nil
}
func (_ Params) Float64(_ string) (float64, error) {
return 0, nil
}
func (_ Params) Int(_ string) (int, error) {
return 0, nil
}
func (_ Params) Int64(_ string) (int64, error) {
return 0, nil
}
func (_ Params) String(_ string) string {
return ""
}
func (_ Params) Uint64(_ string) (uint64, error) {
return 0, nil
}
type Renderer interface {
Render(_ io.Writer, _ string, _ interface{}, _ *Context) error
}
type Route struct{}
func (_ *Route) URL(_ ...string) (*url.URL, error) {
return nil, nil
}

View File

@@ -0,0 +1,6 @@
# clevergo.tech/clevergo v0.5.2
## explicit
clevergo.tech/clevergo
# github.com/github/depstubber v0.0.0-20201214172518-12c3da4b7c9d
## explicit
github.com/github/depstubber

View File

@@ -0,0 +1,105 @@
// Code generated by https://github.com/gagliardetto. DO NOT EDIT.
package main
import "clevergo.tech/clevergo"
func main() {}
func sink(v ...interface{}) {}
// Package clevergo.tech/clevergo@v0.5.2
func ClevergoTechClevergov052() {
// Untrusted flow sources from method calls.
{
// Untrusted flow sources from method calls on clevergo.tech/clevergo.Context.
{
// func (*Context).BasicAuth() (username string, password string, ok bool)
{
var receiverContext656 clevergo.Context
resultUsername414, resultPassword518, _ := receiverContext656.BasicAuth()
sink(
resultUsername414, // $SinkingUntrustedFlowSource
resultPassword518, // $SinkingUntrustedFlowSource
)
}
// func (*Context).Decode(v interface{}) (err error)
{
var receiverContext650 clevergo.Context
var paramV784 interface{}
receiverContext650.Decode(paramV784)
sink(paramV784) // $SinkingUntrustedFlowSource
}
// func (*Context).DefaultQuery(key string, defaultVlue string) string
{
var receiverContext957 clevergo.Context
result520 := receiverContext957.DefaultQuery("", "")
sink(result520) // $SinkingUntrustedFlowSource
}
// func (*Context).FormValue(key string) string
{
var receiverContext443 clevergo.Context
result127 := receiverContext443.FormValue("")
sink(result127) // $SinkingUntrustedFlowSource
}
// func (*Context).GetHeader(name string) string
{
var receiverContext483 clevergo.Context
result989 := receiverContext483.GetHeader("")
sink(result989) // $SinkingUntrustedFlowSource
}
// func (*Context).PostFormValue(key string) string
{
var receiverContext982 clevergo.Context
result417 := receiverContext982.PostFormValue("")
sink(result417) // $SinkingUntrustedFlowSource
}
// func (*Context).QueryParam(key string) string
{
var receiverContext584 clevergo.Context
result991 := receiverContext584.QueryParam("")
sink(result991) // $SinkingUntrustedFlowSource
}
// func (*Context).QueryString() string
{
var receiverContext881 clevergo.Context
result186 := receiverContext881.QueryString()
sink(result186) // $SinkingUntrustedFlowSource
}
}
// Untrusted flow sources from method calls on clevergo.tech/clevergo.Params.
{
// func (Params).String(name string) string
{
var receiverParams284 clevergo.Params
result908 := receiverParams284.String("")
sink(result908) // $SinkingUntrustedFlowSource
}
}
}
// Untrusted flow sources from struct fields.
{
// Untrusted flow sources from clevergo.tech/clevergo.Context struct fields.
{
structContext137 := new(clevergo.Context)
sink(structContext137.Params) // $SinkingUntrustedFlowSource
}
// Untrusted flow sources from clevergo.tech/clevergo.Param struct fields.
{
structParam494 := new(clevergo.Param)
sink(
structParam494.Value, // $SinkingUntrustedFlowSource
structParam494.Key, // $SinkingUntrustedFlowSource
)
}
}
// Untrusted flow sources from types.
{
{
var typeParams873 clevergo.Params
sink(typeParams873) // $SinkingUntrustedFlowSource
}
}
}
//go:generate depstubber -vendor clevergo.tech/clevergo Context,Param,Params
//go:generate depstubber -write_module_txt

View File

@@ -0,0 +1,21 @@
import go
import TestUtilities.InlineExpectationsTest
class UntrustedFlowSourceTest extends InlineExpectationsTest {
UntrustedFlowSourceTest() { this = "UntrustedFlowSourceTest" }
override string getARelevantTag() { result = "SinkingUntrustedFlowSource" }
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
tag = "SinkingUntrustedFlowSource" and
exists(DataFlow::CallNode sinkCall, DataFlow::ArgumentNode arg |
sinkCall.getCalleeName() = "sink" and
arg = sinkCall.getAnArgument() and
arg.getAPredecessor*() instanceof UntrustedFlowSource
|
element = arg.toString() and
value = "" and
arg.hasLocationInfo(file, line, _, _, _)
)
}
}

View File

@@ -0,0 +1,8 @@
module example.com/hello/world
go 1.15
require (
clevergo.tech/clevergo v0.5.2
github.com/github/depstubber v0.0.0-20201214172518-12c3da4b7c9d // indirect
)

View File

@@ -0,0 +1,270 @@
// Code generated by depstubber. DO NOT EDIT.
// This is a simple stub for clevergo.tech/clevergo, strictly for use in testing.
// See the LICENSE file for information about the licensing of the original library.
// Source: clevergo.tech/clevergo (exports: Context,Param,Params; functions: )
// Package clevergo is a stub of clevergo.tech/clevergo, generated by depstubber.
package clevergo
import (
context "context"
io "io"
http "net/http"
url "net/url"
time "time"
)
type Context struct {
Params Params
Route *Route
Request *http.Request
Response http.ResponseWriter
}
func (_ *Context) BasicAuth() (string, string, bool) {
return "", "", false
}
func (_ *Context) Blob(_ int, _ string, _ []byte) error {
return nil
}
func (_ *Context) Context() context.Context {
return nil
}
func (_ *Context) Cookie(_ string) (*http.Cookie, error) {
return nil, nil
}
func (_ *Context) Cookies() []*http.Cookie {
return nil
}
func (_ *Context) Decode(_ interface{}) error {
return nil
}
func (_ *Context) DefaultQuery(_ string, _ string) string {
return ""
}
func (_ *Context) Emit(_ int, _ string, _ string) error {
return nil
}
func (_ *Context) Error(_ int, _ string) error {
return nil
}
func (_ *Context) FormValue(_ string) string {
return ""
}
func (_ *Context) GetHeader(_ string) string {
return ""
}
func (_ *Context) HTML(_ int, _ string) error {
return nil
}
func (_ *Context) HTMLBlob(_ int, _ []byte) error {
return nil
}
func (_ *Context) Host() string {
return ""
}
func (_ *Context) IsAJAX() bool {
return false
}
func (_ *Context) IsDelete() bool {
return false
}
func (_ *Context) IsGet() bool {
return false
}
func (_ *Context) IsMethod(_ string) bool {
return false
}
func (_ *Context) IsOptions() bool {
return false
}
func (_ *Context) IsPatch() bool {
return false
}
func (_ *Context) IsPost() bool {
return false
}
func (_ *Context) IsPut() bool {
return false
}
func (_ *Context) JSON(_ int, _ interface{}) error {
return nil
}
func (_ *Context) JSONBlob(_ int, _ []byte) error {
return nil
}
func (_ *Context) JSONP(_ int, _ interface{}) error {
return nil
}
func (_ *Context) JSONPBlob(_ int, _ []byte) error {
return nil
}
func (_ *Context) JSONPCallback(_ int, _ string, _ interface{}) error {
return nil
}
func (_ *Context) JSONPCallbackBlob(_ int, _ string, _ []byte) error {
return nil
}
func (_ *Context) Logger() interface{} {
return nil
}
func (_ *Context) NotFound() error {
return nil
}
func (_ *Context) PostFormValue(_ string) string {
return ""
}
func (_ *Context) QueryParam(_ string) string {
return ""
}
func (_ *Context) QueryParams() url.Values {
return nil
}
func (_ *Context) QueryString() string {
return ""
}
func (_ *Context) Redirect(_ int, _ string) error {
return nil
}
func (_ *Context) Render(_ int, _ string, _ interface{}) error {
return nil
}
func (_ *Context) RouteURL(_ string, _ ...string) (*url.URL, error) {
return nil, nil
}
func (_ *Context) SendFile(_ string, _ io.Reader) error {
return nil
}
func (_ *Context) ServeContent(_ string, _ time.Time, _ io.ReadSeeker) error {
return nil
}
func (_ *Context) ServeFile(_ string) error {
return nil
}
func (_ *Context) SetContentType(_ string) {}
func (_ *Context) SetContentTypeHTML() {}
func (_ *Context) SetContentTypeJSON() {}
func (_ *Context) SetContentTypeText() {}
func (_ *Context) SetContentTypeXML() {}
func (_ *Context) SetCookie(_ *http.Cookie) {}
func (_ *Context) SetHeader(_ string, _ string) {}
func (_ *Context) String(_ int, _ string) error {
return nil
}
func (_ *Context) StringBlob(_ int, _ []byte) error {
return nil
}
func (_ *Context) Stringf(_ int, _ string, _ ...interface{}) error {
return nil
}
func (_ *Context) Value(_ interface{}) interface{} {
return nil
}
func (_ *Context) WithValue(_ interface{}, _ interface{}) {}
func (_ *Context) Write(_ []byte) (int, error) {
return 0, nil
}
func (_ *Context) WriteHeader(_ int) {}
func (_ *Context) WriteString(_ string) (int, error) {
return 0, nil
}
func (_ *Context) XML(_ int, _ interface{}) error {
return nil
}
func (_ *Context) XMLBlob(_ int, _ []byte) error {
return nil
}
type Param struct {
Key string
Value string
}
type Params []Param
func (_ Params) Bool(_ string) (bool, error) {
return false, nil
}
func (_ Params) Float64(_ string) (float64, error) {
return 0, nil
}
func (_ Params) Int(_ string) (int, error) {
return 0, nil
}
func (_ Params) Int64(_ string) (int64, error) {
return 0, nil
}
func (_ Params) String(_ string) string {
return ""
}
func (_ Params) Uint64(_ string) (uint64, error) {
return 0, nil
}
type Route struct{}
func (_ *Route) URL(_ ...string) (*url.URL, error) {
return nil, nil
}

View File

@@ -0,0 +1,6 @@
# clevergo.tech/clevergo v0.5.2
## explicit
clevergo.tech/clevergo
# github.com/github/depstubber v0.0.0-20201214172518-12c3da4b7c9d
## explicit
github.com/github/depstubber