Merge pull request #438 from gagliardetto/clevergo

Pilot #0: Add web framework `clevergo`
This commit is contained in:
Chris Smowton
2021-04-09 09:48:58 +01:00
committed by GitHub
21 changed files with 1380 additions and 0 deletions

View File

@@ -0,0 +1,379 @@
/**
* Provides classes for working with concepts from the [`clevergo.tech/clevergo@v0.5.2`](https://pkg.go.dev/clevergo.tech/clevergo@v0.5.2) package.
*/
import go
/**
* Provides classes for working with concepts from the [`clevergo.tech/clevergo@v0.5.2`](https://pkg.go.dev/clevergo.tech/clevergo@v0.5.2) package.
*/
private module CleverGo {
/** Gets the package path. */
bindingset[result]
string packagePath() {
result = package(["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 receiverName, string methodName, Method mtd, FunctionOutput out |
this = out.getExitNode(mtd.getACall()) and
mtd.hasQualifiedName(packagePath(), receiverName, methodName)
|
receiverName = "Context" and
(
// signature: func (*Context).BasicAuth() (username string, password string, ok bool)
methodName = "BasicAuth" and
out.isResult([0, 1])
or
// signature: func (*Context).Decode(v interface{}) (err error)
methodName = "Decode" and
out.isParameter(0)
or
// signature: func (*Context).DefaultQuery(key string, defaultVlue string) string
methodName = "DefaultQuery" and
out.isResult()
or
// signature: func (*Context).FormValue(key string) string
methodName = "FormValue" and
out.isResult()
or
// signature: func (*Context).GetHeader(name string) string
methodName = "GetHeader" and
out.isResult()
or
// signature: func (*Context).PostFormValue(key string) string
methodName = "PostFormValue" and
out.isResult()
or
// signature: func (*Context).QueryParam(key string) string
methodName = "QueryParam" and
out.isResult()
or
// signature: func (*Context).QueryParams() net/url.Values
methodName = "QueryParams" and
out.isResult()
or
// signature: func (*Context).QueryString() string
methodName = "QueryString" and
out.isResult()
)
or
receiverName = "Params" and
(
// signature: func (Params).String(name string) string
methodName = "String" and
out.isResult()
)
)
or
// Interfaces of package: clevergo.tech/clevergo@v0.5.2
exists(string interfaceName, string methodName, Method mtd, FunctionOutput out |
this = out.getExitNode(mtd.getACall()) and
mtd.implements(packagePath(), interfaceName, methodName)
|
interfaceName = "Decoder" and
(
// signature: func (Decoder).Decode(req *net/http.Request, v interface{}) error
methodName = "Decode" and
out.isParameter(1)
)
)
or
// Structs of package: clevergo.tech/clevergo@v0.5.2
exists(string structName, string fields, DataFlow::Field fld |
this = fld.getARead() and
fld.hasQualifiedName(packagePath(), structName, fields)
|
structName = "Context" and
fields = "Params"
or
structName = "Param" and
fields = ["Key", "Value"]
)
or
// Types of package: clevergo.tech/clevergo@v0.5.2
exists(ValueEntity v | v.getType().hasQualifiedName(packagePath(), "Params") |
this = v.getARead()
)
}
}
/**
* 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
this.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
(
// Receiver type: Application
// signature: func (*Application).RouteURL(name string, args ...string) (*net/url.URL, error)
this.hasQualifiedName(packagePath(), "Application", "RouteURL") and
inp.isParameter(_) and
out.isResult(0)
or
// Receiver type: Context
// signature: func (*Context).Context() context.Context
this.hasQualifiedName(packagePath(), "Context", "Context") and
inp.isReceiver() and
out.isResult()
or
// Receiver type: Params
// signature: func (Params).String(name string) string
this.hasQualifiedName(packagePath(), "Params", "String") and
inp.isReceiver() and
out.isResult()
or
// Receiver interface: Decoder
// signature: func (Decoder).Decode(req *net/http.Request, v interface{}) error
this.implements(packagePath(), "Decoder", "Decode") and
inp.isParameter(0) and
out.isParameter(1)
or
// Receiver interface: Renderer
// signature: func (Renderer).Render(w io.Writer, name string, data interface{}, c *Context) error
this.implements(packagePath(), "Renderer", "Render") and
inp.isParameter(2) and
out.isParameter(0)
)
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = inp and output = out
}
}
/**
* Models HTTP redirects.
*/
private class HttpRedirect extends HTTP::Redirect::Range, DataFlow::CallNode {
string package;
DataFlow::Node urlNode;
HttpRedirect() {
// HTTP redirect models for package: clevergo.tech/clevergo@v0.5.2
package = packagePath() and
// Receiver type: Context
(
// signature: func (*Context).Redirect(code int, url string) error
this = any(Method m | m.hasQualifiedName(package, "Context", "Redirect")).getACall() and
urlNode = this.getArgument(1)
)
}
override DataFlow::Node getUrl() { result = urlNode }
override HTTP::ResponseWriter getResponseWriter() { none() }
}
/**
* Models HTTP ResponseBody.
*/
private class HttpResponseBody extends HTTP::ResponseBody::Range {
string package;
DataFlow::CallNode bodySetterCall;
string contentType;
HttpResponseBody() {
// HTTP ResponseBody models for package: clevergo.tech/clevergo@v0.5.2
package = packagePath() and
(
// One call sets both body and content-type (which is implicit in the func name).
// Receiver type: Context
exists(string methodName, Method m |
m.hasQualifiedName(package, "Context", methodName) and
bodySetterCall = m.getACall()
|
// signature: func (*Context).Error(code int, msg string) error
methodName = "Error" and
this = bodySetterCall.getArgument(1) and
contentType = "text/plain"
or
// signature: func (*Context).HTML(code int, html string) error
methodName = "HTML" and
this = bodySetterCall.getArgument(1) and
contentType = "text/html"
or
// signature: func (*Context).HTMLBlob(code int, bs []byte) error
methodName = "HTMLBlob" and
this = bodySetterCall.getArgument(1) and
contentType = "text/html"
or
// signature: func (*Context).JSON(code int, data interface{}) error
methodName = "JSON" and
this = bodySetterCall.getArgument(1) and
contentType = "application/json"
or
// signature: func (*Context).JSONBlob(code int, bs []byte) error
methodName = "JSONBlob" and
this = bodySetterCall.getArgument(1) and
contentType = "application/json"
or
// signature: func (*Context).JSONP(code int, data interface{}) error
methodName = "JSONP" and
this = bodySetterCall.getArgument(1) and
contentType = "application/javascript"
or
// signature: func (*Context).JSONPBlob(code int, bs []byte) error
methodName = "JSONPBlob" and
this = bodySetterCall.getArgument(1) and
contentType = "application/javascript"
or
// signature: func (*Context).JSONPCallback(code int, callback string, data interface{}) error
methodName = "JSONPCallback" and
this = bodySetterCall.getArgument(2) and
contentType = "application/javascript"
or
// signature: func (*Context).JSONPCallbackBlob(code int, callback string, bs []byte) (err error)
methodName = "JSONPCallbackBlob" and
this = bodySetterCall.getArgument(2) and
contentType = "application/javascript"
or
// signature: func (*Context).String(code int, s string) error
methodName = "String" and
this = bodySetterCall.getArgument(1) and
contentType = "text/plain"
or
// signature: func (*Context).StringBlob(code int, bs []byte) error
methodName = "StringBlob" and
this = bodySetterCall.getArgument(1) and
contentType = "text/plain"
or
// signature: func (*Context).Stringf(code int, format string, a ...interface{}) error
methodName = "Stringf" and
this = bodySetterCall.getArgument([1, any(int i | i >= 2)]) and
contentType = "text/plain"
or
// signature: func (*Context).XML(code int, data interface{}) error
methodName = "XML" and
this = bodySetterCall.getArgument(1) and
contentType = "text/xml"
or
// signature: func (*Context).XMLBlob(code int, bs []byte) error
methodName = "XMLBlob" and
this = bodySetterCall.getArgument(1) and
contentType = "text/xml"
)
or
// One call sets both body and content-type (both are parameters in the func call).
// Receiver type: Context
exists(string methodName, Method m |
m.hasQualifiedName(package, "Context", methodName) and
bodySetterCall = m.getACall()
|
// signature: func (*Context).Blob(code int, contentType string, bs []byte) (err error)
methodName = "Blob" and
this = bodySetterCall.getArgument(2) and
contentType = bodySetterCall.getArgument(1).getStringValue()
or
// signature: func (*Context).Emit(code int, contentType string, body string) (err error)
methodName = "Emit" and
this = bodySetterCall.getArgument(2) and
contentType = bodySetterCall.getArgument(1).getStringValue()
)
or
// Two calls, one to set the response body and one to set the content-type.
// Receiver type: Context
exists(string methodName, Method m |
m.hasQualifiedName(package, "Context", methodName) and
bodySetterCall = m.getACall()
|
// signature: func (*Context).Write(data []byte) (int, error)
methodName = "Write" and
this = bodySetterCall.getArgument(0)
or
// signature: func (*Context).WriteString(data string) (int, error)
methodName = "WriteString" and
this = bodySetterCall.getArgument(0)
) and
(
// Receiver type: Context
exists(string methodName, Method m, DataFlow::CallNode contentTypeSetterCall |
m.hasQualifiedName(package, "Context", methodName) and
contentTypeSetterCall = m.getACall() and
contentTypeSetterCall.getReceiver().getAPredecessor*() =
bodySetterCall.getReceiver().getAPredecessor*()
|
// signature: func (*Context).SetContentType(v string)
methodName = "SetContentType" and
contentType = contentTypeSetterCall.getArgument(0).getStringValue()
)
or
// Receiver type: Context
exists(string methodName, Method m, DataFlow::CallNode contentTypeSetterCall |
m.hasQualifiedName(package, "Context", methodName) and
contentTypeSetterCall = m.getACall() and
contentTypeSetterCall.getReceiver().getAPredecessor*() =
bodySetterCall.getReceiver().getAPredecessor*()
|
// signature: func (*Context).SetContentTypeHTML()
methodName = "SetContentTypeHTML" and
contentType = "text/html"
or
// signature: func (*Context).SetContentTypeJSON()
methodName = "SetContentTypeJSON" and
contentType = "application/json"
or
// signature: func (*Context).SetContentTypeText()
methodName = "SetContentTypeText" and
contentType = "text/plain"
or
// signature: func (*Context).SetContentTypeXML()
methodName = "SetContentTypeXML" and
contentType = "text/xml"
)
)
)
}
override string getAContentType() { result = contentType }
override HTTP::ResponseWriter getResponseWriter() { none() }
}
/**
* Models a HTTP header writer model for package: clevergo.tech/clevergo@v0.5.2
*/
private class HeaderWrite extends HTTP::HeaderWrite::Range, DataFlow::CallNode {
HeaderWrite() {
// Receiver type: Context
// signature: func (*Context).SetHeader(key string, value string)
this = any(Method m | m.hasQualifiedName(packagePath(), "Context", "SetHeader")).getACall()
}
override DataFlow::Node getName() { result = this.getArgument(0) }
override DataFlow::Node getValue() { result = this.getArgument(1) }
override HTTP::ResponseWriter getResponseWriter() { none() }
}
}

View File

@@ -0,0 +1,22 @@
// Code generated by https://github.com/gagliardetto. DO NOT EDIT.
package main
import "clevergo.tech/clevergo"
// Package clevergo.tech/clevergo@v0.5.2
func HeaderWrite_ClevergoTechClevergov052() {
// Header write via method calls.
{
// Header write via method calls on clevergo.tech/clevergo.Context.
{
// func (*Context).SetHeader(key string, value string)
{
keyString566 := source().(string)
valString497 := source().(string)
var rece clevergo.Context
rece.SetHeader(keyString566, valString497) // $headerKey=keyString566 $headerVal=valString497
}
}
}
}

View File

@@ -0,0 +1,24 @@
import go
import experimental.frameworks.CleverGo
import TestUtilities.InlineExpectationsTest
class HttpHeaderWriteTest extends InlineExpectationsTest {
HttpHeaderWriteTest() { this = "HttpHeaderWriteTest" }
override string getARelevantTag() { result = ["headerKey", "headerVal"] }
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
exists(HTTP::HeaderWrite hw |
hw.hasLocationInfo(file, line, _, _, _) and
(
element = hw.getName().toString() and
value = hw.getName().toString() and
tag = "headerKey"
or
element = hw.getValue().toString() and
value = hw.getValue().toString() and
tag = "headerVal"
)
)
}
}

View File

@@ -0,0 +1,21 @@
// Code generated by https://github.com/gagliardetto. DO NOT EDIT.
package main
import "clevergo.tech/clevergo"
// Package clevergo.tech/clevergo@v0.5.2
func HttpRedirect_ClevergoTechClevergov052() {
// Redirect via method calls.
{
// Redirect via method calls on clevergo.tech/clevergo.Context.
{
// func (*Context).Redirect(code int, url string) error
{
urlString316 := source().(string)
var rece clevergo.Context
rece.Redirect(0, urlString316) // $redirectUrl=urlString316
}
}
}
}

View File

@@ -0,0 +1,18 @@
import go
import experimental.frameworks.CleverGo
import TestUtilities.InlineExpectationsTest
class HttpRedirectTest extends InlineExpectationsTest {
HttpRedirectTest() { this = "HttpRedirectTest" }
override string getARelevantTag() { result = "redirectUrl" }
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
tag = "redirectUrl" and
exists(HTTP::Redirect rd |
rd.hasLocationInfo(file, line, _, _, _) and
element = rd.getUrl().toString() and
value = rd.getUrl().toString()
)
}
}

View File

@@ -0,0 +1,186 @@
// Code generated by https://github.com/gagliardetto. DO NOT EDIT.
package main
import "clevergo.tech/clevergo"
// Package clevergo.tech/clevergo@v0.5.2
func HttpResponseBody_ClevergoTechClevergov052() {
// Response body is set via a method call (the content-type is implicit in the method name).
{
// Response body is set via a method call on the clevergo.tech/clevergo.Context type (the content-type is implicit in the method name).
{
// func (*Context).Error(code int, msg string) error
{
bodyString145 := source().(string)
var rece clevergo.Context
rece.Error(0, bodyString145) // $contentType=text/plain $responseBody=bodyString145
}
// func (*Context).HTML(code int, html string) error
{
bodyString817 := source().(string)
var rece clevergo.Context
rece.HTML(0, bodyString817) // $contentType=text/html $responseBody=bodyString817
}
// func (*Context).HTMLBlob(code int, bs []byte) error
{
bodyByte474 := source().([]byte)
var rece clevergo.Context
rece.HTMLBlob(0, bodyByte474) // $contentType=text/html $responseBody=bodyByte474
}
// func (*Context).JSON(code int, data interface{}) error
{
bodyInterface832 := source().(interface{})
var rece clevergo.Context
rece.JSON(0, bodyInterface832) // $contentType=application/json $responseBody=bodyInterface832
}
// func (*Context).JSONBlob(code int, bs []byte) error
{
bodyByte378 := source().([]byte)
var rece clevergo.Context
rece.JSONBlob(0, bodyByte378) // $contentType=application/json $responseBody=bodyByte378
}
// func (*Context).JSONP(code int, data interface{}) error
{
bodyInterface541 := source().(interface{})
var rece clevergo.Context
rece.JSONP(0, bodyInterface541) // $contentType=application/javascript $responseBody=bodyInterface541
}
// func (*Context).JSONPBlob(code int, bs []byte) error
{
bodyByte139 := source().([]byte)
var rece clevergo.Context
rece.JSONPBlob(0, bodyByte139) // $contentType=application/javascript $responseBody=bodyByte139
}
// func (*Context).JSONPCallback(code int, callback string, data interface{}) error
{
bodyInterface814 := source().(interface{})
var rece clevergo.Context
rece.JSONPCallback(0, "", bodyInterface814) // $contentType=application/javascript $responseBody=bodyInterface814
}
// func (*Context).JSONPCallbackBlob(code int, callback string, bs []byte) (err error)
{
bodyByte768 := source().([]byte)
var rece clevergo.Context
rece.JSONPCallbackBlob(0, "", bodyByte768) // $contentType=application/javascript $responseBody=bodyByte768
}
// func (*Context).String(code int, s string) error
{
bodyString468 := source().(string)
var rece clevergo.Context
rece.String(0, bodyString468) // $contentType=text/plain $responseBody=bodyString468
}
// func (*Context).StringBlob(code int, bs []byte) error
{
bodyByte736 := source().([]byte)
var rece clevergo.Context
rece.StringBlob(0, bodyByte736) // $contentType=text/plain $responseBody=bodyByte736
}
// func (*Context).Stringf(code int, format string, a ...interface{}) error
{
bodyString516 := source().(string)
bodyInterface246 := source().(interface{})
var rece clevergo.Context
rece.Stringf(0, bodyString516, bodyInterface246) // $contentType=text/plain $responseBody=bodyString516 $responseBody=bodyInterface246
}
// func (*Context).XML(code int, data interface{}) error
{
bodyInterface679 := source().(interface{})
var rece clevergo.Context
rece.XML(0, bodyInterface679) // $contentType=text/xml $responseBody=bodyInterface679
}
// func (*Context).XMLBlob(code int, bs []byte) error
{
bodyByte736 := source().([]byte)
var rece clevergo.Context
rece.XMLBlob(0, bodyByte736) // $contentType=text/xml $responseBody=bodyByte736
}
}
}
// Response body and content-type are both set via a single call of a method.
{
// Response body and content-type are both set via a single call of a method on the clevergo.tech/clevergo.Context type.
{
// func (*Context).Blob(code int, contentType string, bs []byte) (err error)
{
bodyByte839 := source().([]byte)
var rece clevergo.Context
rece.Blob(0, "application/json", bodyByte839) // $contentType=application/json $responseBody=bodyByte839
}
// func (*Context).Emit(code int, contentType string, body string) (err error)
{
bodyString273 := source().(string)
var rece clevergo.Context
rece.Emit(0, "application/json", bodyString273) // $contentType=application/json $responseBody=bodyString273
}
}
}
// Response body and content-type are set via calls of different methods.
{
// Response body and content-type are set via calls of different methods on the clevergo.tech/clevergo.Context type.
{
// func (*Context).Write(data []byte) (int, error)
{
bodyByte982 := source().([]byte)
var rece clevergo.Context
rece.SetContentType("application/json")
rece.Write(bodyByte982) // $contentType=application/json $responseBody=bodyByte982
}
{
bodyByte458 := source().([]byte)
var rece clevergo.Context
rece.SetContentTypeHTML()
rece.Write(bodyByte458) // $contentType=text/html $responseBody=bodyByte458
}
{
bodyByte506 := source().([]byte)
var rece clevergo.Context
rece.SetContentTypeJSON()
rece.Write(bodyByte506) // $contentType=application/json $responseBody=bodyByte506
}
{
bodyByte213 := source().([]byte)
var rece clevergo.Context
rece.SetContentTypeText()
rece.Write(bodyByte213) // $contentType=text/plain $responseBody=bodyByte213
}
{
bodyByte468 := source().([]byte)
var rece clevergo.Context
rece.SetContentTypeXML()
rece.Write(bodyByte468) // $contentType=text/xml $responseBody=bodyByte468
}
// func (*Context).WriteString(data string) (int, error)
{
bodyString219 := source().(string)
var rece clevergo.Context
rece.SetContentType("application/json")
rece.WriteString(bodyString219) // $contentType=application/json $responseBody=bodyString219
}
{
bodyString265 := source().(string)
var rece clevergo.Context
rece.SetContentTypeHTML()
rece.WriteString(bodyString265) // $contentType=text/html $responseBody=bodyString265
}
{
bodyString971 := source().(string)
var rece clevergo.Context
rece.SetContentTypeJSON()
rece.WriteString(bodyString971) // $contentType=application/json $responseBody=bodyString971
}
{
bodyString320 := source().(string)
var rece clevergo.Context
rece.SetContentTypeText()
rece.WriteString(bodyString320) // $contentType=text/plain $responseBody=bodyString320
}
{
bodyString545 := source().(string)
var rece clevergo.Context
rece.SetContentTypeXML()
rece.WriteString(bodyString545) // $contentType=text/xml $responseBody=bodyString545
}
}
}
}

View File

@@ -0,0 +1,24 @@
import go
import experimental.frameworks.CleverGo
import TestUtilities.InlineExpectationsTest
class HttpResponseBodyTest extends InlineExpectationsTest {
HttpResponseBodyTest() { this = "HttpResponseBodyTest" }
override string getARelevantTag() { result = ["contentType", "responseBody"] }
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
exists(HTTP::ResponseBody rd |
rd.hasLocationInfo(file, line, _, _, _) and
(
element = rd.getAContentType().toString() and
value = rd.getAContentType().toString() and
tag = "contentType"
or
element = rd.toString() and
value = rd.toString() and
tag = "responseBody"
)
)
}
}

View File

@@ -0,0 +1,87 @@
// Code generated by https://github.com/gagliardetto. DO NOT EDIT.
package main
import (
"io"
"net/http"
"clevergo.tech/clevergo"
)
// Package clevergo.tech/clevergo@v0.5.2
func TaintTracking_ClevergoTechClevergov052() {
// Taint-tracking through functions.
{
// func CleanPath(p string) string
{
fromString598 := source().(string)
intoString631 := clevergo.CleanPath(fromString598)
sink(intoString631) // $taintSink
}
}
// Taint-tracking through method calls.
{
// Taint-tracking through method calls on clevergo.tech/clevergo.Application.
{
// func (*Application).RouteURL(name string, args ...string) (*net/url.URL, error)
{
{
fromString165 := source().(string)
var mediumObjCQL clevergo.Application
intoURL150, _ := mediumObjCQL.RouteURL(fromString165, "")
sink(intoURL150) // $taintSink
}
{
fromString340 := source().(string)
var mediumObjCQL clevergo.Application
intoURL471, _ := mediumObjCQL.RouteURL("", fromString340)
sink(intoURL471) // $taintSink
}
}
}
// Taint-tracking through method calls on clevergo.tech/clevergo.Context.
{
// func (*Context).Context() context.Context
{
fromContext290 := source().(clevergo.Context)
intoContext758 := fromContext290.Context()
sink(intoContext758) // $taintSink
}
}
// Taint-tracking through method calls on clevergo.tech/clevergo.Params.
{
// func (Params).String(name string) string
{
fromParams396 := source().(clevergo.Params)
intoString707 := fromParams396.String("")
sink(intoString707) // $taintSink $untrustedFlowSource
}
}
}
// 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
{
fromRequest912 := source().(*http.Request)
var intoInterface718 interface{}
var mediumObjCQL clevergo.Decoder
mediumObjCQL.Decode(fromRequest912, intoInterface718)
sink(intoInterface718) // $taintSink $untrustedFlowSource
}
}
// Taint-tracking through method calls on clevergo.tech/clevergo.Renderer interface.
{
// func (Renderer).Render(w io.Writer, name string, data interface{}, c *Context) error
{
fromInterface972 := source().(interface{})
var intoWriter633 io.Writer
var mediumObjCQL clevergo.Renderer
mediumObjCQL.Render(intoWriter633, "", fromInterface972, nil)
sink(intoWriter633) // $taintSink
}
}
}
}

View File

@@ -0,0 +1,30 @@
import go
import experimental.frameworks.CleverGo
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 = "taintSink" }
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
tag = "taintSink" 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,118 @@
// Code generated by https://github.com/gagliardetto. DO NOT EDIT.
package main
import "clevergo.tech/clevergo"
// Package clevergo.tech/clevergo@v0.5.2
func UntrustedSources_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, // $untrustedFlowSource
resultPassword518, // $untrustedFlowSource
)
}
// func (*Context).Decode(v interface{}) (err error)
{
var receiverContext650 clevergo.Context
var paramV784 interface{}
receiverContext650.Decode(paramV784)
sink(paramV784) // $untrustedFlowSource
}
// func (*Context).DefaultQuery(key string, defaultVlue string) string
{
var receiverContext957 clevergo.Context
result520 := receiverContext957.DefaultQuery("", "")
sink(result520) // $untrustedFlowSource
}
// func (*Context).FormValue(key string) string
{
var receiverContext443 clevergo.Context
result127 := receiverContext443.FormValue("")
sink(result127) // $untrustedFlowSource
}
// func (*Context).GetHeader(name string) string
{
var receiverContext483 clevergo.Context
result989 := receiverContext483.GetHeader("")
sink(result989) // $untrustedFlowSource
}
// func (*Context).PostFormValue(key string) string
{
var receiverContext982 clevergo.Context
result417 := receiverContext982.PostFormValue("")
sink(result417) // $untrustedFlowSource
}
// func (*Context).QueryParam(key string) string
{
var receiverContext584 clevergo.Context
result991 := receiverContext584.QueryParam("")
sink(result991) // $untrustedFlowSource
}
// func (*Context).QueryParams() net/url.Values
{
var receiverContext881 clevergo.Context
result186 := receiverContext881.QueryParams()
sink(result186) // $untrustedFlowSource
}
// func (*Context).QueryString() string
{
var receiverContext284 clevergo.Context
result908 := receiverContext284.QueryString()
sink(result908) // $untrustedFlowSource
}
}
// Untrusted flow sources from method calls on clevergo.tech/clevergo.Params.
{
// func (Params).String(name string) string
{
var receiverParams137 clevergo.Params
result494 := receiverParams137.String("")
sink(result494) // $untrustedFlowSource
}
}
}
// Untrusted flow sources from interface method calls.
{
// Untrusted flow sources from method calls on clevergo.tech/clevergo.Decoder interface.
{
// func (Decoder).Decode(req *net/http.Request, v interface{}) error
{
var receiverDecoder873 clevergo.Decoder
var paramV599 interface{}
receiverDecoder873.Decode(nil, paramV599)
sink(paramV599) // $untrustedFlowSource
}
}
}
// Untrusted flow sources from struct fields.
{
// Untrusted flow sources from clevergo.tech/clevergo.Context struct fields.
{
structContext409 := new(clevergo.Context)
sink(structContext409.Params) // $untrustedFlowSource
}
// Untrusted flow sources from clevergo.tech/clevergo.Param struct fields.
{
structParam246 := new(clevergo.Param)
sink(
structParam246.Key, // $untrustedFlowSource
structParam246.Value, // $untrustedFlowSource
)
}
}
// Untrusted flow sources from types.
{
{
var typeParams898 clevergo.Params
sink(typeParams898) // $untrustedFlowSource
}
}
}

View File

@@ -0,0 +1,22 @@
import go
import experimental.frameworks.CleverGo
import TestUtilities.InlineExpectationsTest
class UntrustedFlowSourceTest extends InlineExpectationsTest {
UntrustedFlowSourceTest() { this = "UntrustedFlowSourceTest" }
override string getARelevantTag() { result = "untrustedFlowSource" }
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
tag = "untrustedFlowSource" 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,5 @@
module example.com/hello/world
go 1.15
require clevergo.tech/clevergo v0.5.2

View File

@@ -0,0 +1,12 @@
//go:generate depstubber --vendor --auto
package main
func main() {}
func source() interface{} {
return nil
}
func sink(v ...interface{}) {}
func link(from interface{}, into interface{}) {}

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 CleverGo
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.

View File

@@ -0,0 +1,408 @@
// 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: Application,Context,Decoder,Param,Params,Renderer; functions: CleanPath)
// Package clevergo is a stub of clevergo.tech/clevergo, generated by depstubber.
package clevergo
import (
context "context"
io "io"
net "net"
http "net/http"
url "net/url"
os "os"
time "time"
)
type Application struct {
Server *http.Server
ShutdownTimeout time.Duration
ShutdownSignals []os.Signal
RedirectTrailingSlash bool
RedirectFixedPath bool
HandleMethodNotAllowed bool
HandleOPTIONS bool
GlobalOPTIONS http.Handler
NotFound http.Handler
MethodNotAllowed http.Handler
UseRawPath bool
Renderer Renderer
Decoder Decoder
Logger interface{}
}
func (_ *Application) Any(_ string, _ Handle, _ ...RouteOption) {}
func (_ *Application) Delete(_ string, _ Handle, _ ...RouteOption) {}
func (_ *Application) Get(_ string, _ Handle, _ ...RouteOption) {}
func (_ *Application) Group(_ string, _ ...RouteGroupOption) Router {
return nil
}
func (_ *Application) Handle(_ string, _ string, _ Handle, _ ...RouteOption) {}
func (_ *Application) Handler(_ string, _ string, _ http.Handler, _ ...RouteOption) {}
func (_ *Application) HandlerFunc(_ string, _ string, _ http.HandlerFunc, _ ...RouteOption) {}
func (_ *Application) Head(_ string, _ Handle, _ ...RouteOption) {}
func (_ *Application) Lookup(_ string, _ string) (*Route, Params, bool) {
return nil, nil, false
}
func (_ *Application) Options(_ string, _ Handle, _ ...RouteOption) {}
func (_ *Application) Patch(_ string, _ Handle, _ ...RouteOption) {}
func (_ *Application) Post(_ string, _ Handle, _ ...RouteOption) {}
func (_ *Application) Put(_ string, _ Handle, _ ...RouteOption) {}
func (_ *Application) RouteURL(_ string, _ ...string) (*url.URL, error) {
return nil, nil
}
func (_ *Application) Run(_ string) error {
return nil
}
func (_ *Application) RunTLS(_ string, _ string, _ string) error {
return nil
}
func (_ *Application) RunUnix(_ string) error {
return nil
}
func (_ *Application) Serve(_ net.Listener) error {
return nil
}
func (_ *Application) ServeFiles(_ string, _ http.FileSystem, _ ...RouteOption) {}
func (_ *Application) ServeHTTP(_ http.ResponseWriter, _ *http.Request) {}
func (_ *Application) Use(_ ...MiddlewareFunc) {}
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 Handle func(*Context) error
type MiddlewareFunc func(Handle) Handle
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
}
type RouteGroup struct{}
func (_ *RouteGroup) Any(_ string, _ Handle, _ ...RouteOption) {}
func (_ *RouteGroup) Delete(_ string, _ Handle, _ ...RouteOption) {}
func (_ *RouteGroup) Get(_ string, _ Handle, _ ...RouteOption) {}
func (_ *RouteGroup) Group(_ string, _ ...RouteGroupOption) Router {
return nil
}
func (_ *RouteGroup) Handle(_ string, _ string, _ Handle, _ ...RouteOption) {}
func (_ *RouteGroup) Handler(_ string, _ string, _ http.Handler, _ ...RouteOption) {}
func (_ *RouteGroup) HandlerFunc(_ string, _ string, _ http.HandlerFunc, _ ...RouteOption) {}
func (_ *RouteGroup) Head(_ string, _ Handle, _ ...RouteOption) {}
func (_ *RouteGroup) Options(_ string, _ Handle, _ ...RouteOption) {}
func (_ *RouteGroup) Patch(_ string, _ Handle, _ ...RouteOption) {}
func (_ *RouteGroup) Post(_ string, _ Handle, _ ...RouteOption) {}
func (_ *RouteGroup) Put(_ string, _ Handle, _ ...RouteOption) {}
type RouteGroupOption func(*RouteGroup)
type RouteOption func(*Route)
type Router interface {
Any(_ string, _ Handle, _ ...RouteOption)
Delete(_ string, _ Handle, _ ...RouteOption)
Get(_ string, _ Handle, _ ...RouteOption)
Group(_ string, _ ...RouteGroupOption) Router
Handle(_ string, _ string, _ Handle, _ ...RouteOption)
Handler(_ string, _ string, _ http.Handler, _ ...RouteOption)
HandlerFunc(_ string, _ string, _ http.HandlerFunc, _ ...RouteOption)
Head(_ string, _ Handle, _ ...RouteOption)
Options(_ string, _ Handle, _ ...RouteOption)
Patch(_ string, _ Handle, _ ...RouteOption)
Post(_ string, _ Handle, _ ...RouteOption)
Put(_ string, _ Handle, _ ...RouteOption)
}

View File

@@ -0,0 +1,3 @@
# clevergo.tech/clevergo v0.5.2
## explicit
clevergo.tech/clevergo