mirror of
https://github.com/github/codeql.git
synced 2026-04-27 01:35:13 +02:00
Convert path-injection sinks to use MaD
This commit is contained in:
@@ -6,6 +6,11 @@ extensions:
|
||||
- ["beego-context", "github.com/astaxie/beego/context"]
|
||||
- ["beego-context", "github.com/beego/beego/context"]
|
||||
- ["beego-context", "github.com/beego/beego/server/web/context"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["group:beego-context", "BeegoOutput", False, "Download", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
|
||||
@@ -10,6 +10,7 @@ extensions:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
# log-injection
|
||||
- ["group:beego", "", False, "Alert", "", "", "Argument[0..1]", "log-injection", "manual"]
|
||||
- ["group:beego", "", False, "Critical", "", "", "Argument[0..1]", "log-injection", "manual"]
|
||||
- ["group:beego", "", False, "Debug", "", "", "Argument[0..1]", "log-injection", "manual"]
|
||||
@@ -21,6 +22,11 @@ extensions:
|
||||
- ["group:beego", "", False, "Trace", "", "", "Argument[0..1]", "log-injection", "manual"]
|
||||
- ["group:beego", "", False, "Warn", "", "", "Argument[0..1]", "log-injection", "manual"]
|
||||
- ["group:beego", "", False, "Warning", "", "", "Argument[0..1]", "log-injection", "manual"]
|
||||
# path-injection
|
||||
- ["group:beego", "", False, "Walk", "", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["group:beego", "Controller", False, "SaveToFile", "", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["group:beego", "Controller", False, "SaveToFileWithBuffer", "", "", "Argument[1]", "path-injection", "manual"] # only exists in v2
|
||||
- ["group:beego", "FileSystem", False, "Open", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/gin-gonic/gin", "Context", False, "File", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/gin-gonic/gin", "Context", False, "FileAttachment", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/gin-gonic/gin", "Context", False, "SaveUploadedFile", "", "", "Argument[1]", "path-injection", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
|
||||
9
go/ql/lib/ext/github.com.gofiber.fiber.model.yml
Normal file
9
go/ql/lib/ext/github.com.gofiber.fiber.model.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/gofiber/fiber", "Ctx", False, "SendFile", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/gofiber/fiber", "Ctx", False, "Download", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/gofiber/fiber", "Ctx", False, "SaveFile", "", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["github.com/gofiber/fiber", "Ctx", False, "SaveFileToStorage", "", "", "Argument[1]", "path-injection", "manual"] # does not exist in v1
|
||||
17
go/ql/lib/ext/github.com.kataras.iris.context.model.yml
Normal file
17
go/ql/lib/ext/github.com.kataras.iris.context.model.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: packageGrouping
|
||||
data:
|
||||
- ["iris-context", "github.com/kataras/iris/context"]
|
||||
- ["iris-context", "github.com/kataras/iris/server/web/context"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["group:iris-context", "Context", True, "SendFile", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["group:iris-context", "Context", True, "ServeFile", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["group:iris-context", "Context", True, "SendFileWithRate", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["group:iris-context", "Context", True, "ServeFileWithRate", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["group:iris-context", "Context", True, "UploadFormFiles", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["group:iris-context", "Context", True, "SaveFormFile", "", "", "Argument[1]", "path-injection", "manual"]
|
||||
@@ -1,4 +1,10 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/labstack/echo", "Context", False, "Attachment", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/labstack/echo", "Context", False, "File", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
|
||||
@@ -32,6 +32,11 @@ extensions:
|
||||
- ["group:revel", "Request", True, "UserAgent", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["group:revel", "ServerWebSocket", True, "MessageReceive", "", "", "Argument[0]", "remote", "manual"]
|
||||
- ["group:revel", "ServerWebSocket", True, "MessageReceiveJSON", "", "", "Argument[0]", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["group:revel", "Controller", True, "RenderFileName", "", "", "Argument[0]", "path-injection", "manual"] # we model this as a path-injection sink rather than extending HTTP::ResponseBody as this will usually mean exposing a user-controlled file rather than the actual contents being user-controlled.
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
|
||||
39
go/ql/lib/ext/github.com.spf13.afero.model.yml
Normal file
39
go/ql/lib/ext/github.com.spf13.afero.model.yml
Normal file
@@ -0,0 +1,39 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/spf13/afero", "HttpFs", False, "Create", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "HttpFs", False, "Open", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "HttpFs", False, "OpenFile", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "HttpFs", False, "Remove", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "HttpFs", False, "RemoveAll", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "MemMapFs", False, "Create", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "MemMapFs", False, "Open", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "MemMapFs", False, "OpenFile", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "MemMapFs", False, "Remove", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "MemMapFs", False, "RemoveAll", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "MemMapFs", False, "Mkdir", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "MemMapFs", False, "MkdirAll", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "OsFs", False, "Create", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "OsFs", False, "Open", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "OsFs", False, "OpenFile", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "OsFs", False, "ReadlinkIfPossible", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "OsFs", False, "Remove", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "OsFs", False, "RemoveAll", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "OsFs", False, "Mkdir", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "OsFs", False, "MkdirAll", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "ReadOnlyFs", False, "Create", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "ReadOnlyFs", False, "Open", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "ReadOnlyFs", False, "OpenFile", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "ReadOnlyFs", False, "ReadDir", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "ReadOnlyFs", False, "ReadlinkIfPossible", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "ReadOnlyFs", False, "Mkdir", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "ReadOnlyFs", False, "MkdirAll", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "RegexpFs", False, "Create", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "RegexpFs", False, "Open", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "RegexpFs", False, "OpenFile", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "RegexpFs", False, "Remove", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "RegexpFs", False, "RemoveAll", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "RegexpFs", False, "Mkdir", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/spf13/afero", "RegexpFs", False, "MkdirAll", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
@@ -3,6 +3,7 @@ extensions:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
# request-forgery
|
||||
- ["github.com/valyala/fasthttp", "", True, "Get", "", "", "Argument[1]", "request-forgery", "manual"]
|
||||
- ["github.com/valyala/fasthttp", "", True, "GetDeadline", "", "", "Argument[1]", "request-forgery", "manual"]
|
||||
- ["github.com/valyala/fasthttp", "", True, "GetTimeout", "", "", "Argument[1]", "request-forgery", "manual"]
|
||||
@@ -28,6 +29,15 @@ extensions:
|
||||
- ["github.com/valyala/fasthttp", "TCPDialer", True, "DialDualStack", "", "", "Argument[0]", "request-forgery[TCP Addr + Port]", "manual"]
|
||||
- ["github.com/valyala/fasthttp", "TCPDialer", True, "DialDualStackTimeout", "", "", "Argument[0]", "request-forgery[TCP Addr + Port]", "manual"]
|
||||
- ["github.com/valyala/fasthttp", "TCPDialer", True, "DialTimeout", "", "", "Argument[0]", "request-forgery[TCP Addr + Port]", "manual"]
|
||||
# path-injection
|
||||
- ["github.com/valyala/fasthttp", "", False, "SaveMultipartFile", "", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["github.com/valyala/fasthttp", "", False, "ServeFile", "", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["github.com/valyala/fasthttp", "", False, "ServeFileBytes", "", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["github.com/valyala/fasthttp", "", False, "ServeFileBytesUncompressed", "", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["github.com/valyala/fasthttp", "", False, "ServeFileUncompressed", "", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["github.com/valyala/fasthttp", "RequestCtx", False, "SendFile", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/valyala/fasthttp", "RequestCtx", False, "SendFileBytes", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["github.com/valyala/fasthttp", "Response", False, "SendFile", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["io/ioutil", "", False, "ReadDir", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["io/ioutil", "", False, "ReadFile", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["io/ioutil", "", False, "TempDir", "", "", "Argument[0..1]", "path-injection", "manual"]
|
||||
- ["io/ioutil", "", False, "TempFile", "", "", "Argument[0..1]", "path-injection", "manual"]
|
||||
- ["io/ioutil", "", False, "WriteFile", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["net/http", "", False, "ServeFile", "", "", "Argument[2]", "path-injection", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
|
||||
@@ -1,4 +1,34 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["os", "", False, "Chdir", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "Chmod", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "Chown", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "Chtimes", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "Create", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "Lchown", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "Link", "", "", "Argument[0..1]", "path-injection", "manual"]
|
||||
- ["os", "", False, "Lstat", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "Mkdir", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "MkdirAll", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "NewFile", "", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["os", "", False, "Open", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "OpenFile", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "Readlink", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "Remove", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "RemoveAll", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "Rename", "", "", "Argument[0..1]", "path-injection", "manual"]
|
||||
- ["os", "", False, "Stat", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "Symlink", "", "", "Argument[0..1]", "path-injection", "manual"]
|
||||
- ["os", "", False, "Truncate", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "DirFS", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "ReadDir", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "ReadFile", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- ["os", "", False, "MkdirTemp", "", "", "Argument[0..1]", "path-injection", "manual"]
|
||||
- ["os", "", False, "CreateTemp", "", "", "Argument[0..1]", "path-injection", "manual"]
|
||||
- ["os", "", False, "WriteFile", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
|
||||
@@ -40,15 +40,12 @@ import semmle.go.frameworks.ElazarlGoproxy
|
||||
import semmle.go.frameworks.Email
|
||||
import semmle.go.frameworks.Encoding
|
||||
import semmle.go.frameworks.Fasthttp
|
||||
import semmle.go.frameworks.Fiber
|
||||
import semmle.go.frameworks.Gin
|
||||
import semmle.go.frameworks.GinCors
|
||||
import semmle.go.frameworks.Glog
|
||||
import semmle.go.frameworks.GoJose
|
||||
import semmle.go.frameworks.GoKit
|
||||
import semmle.go.frameworks.GoMicro
|
||||
import semmle.go.frameworks.Gqlgen
|
||||
import semmle.go.frameworks.Iris
|
||||
import semmle.go.frameworks.Jwt
|
||||
import semmle.go.frameworks.K8sIoApimachineryPkgRuntime
|
||||
import semmle.go.frameworks.K8sIoApiCoreV1
|
||||
|
||||
@@ -112,6 +112,23 @@ module FileSystemAccess {
|
||||
}
|
||||
}
|
||||
|
||||
private class DefaultFileSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
DataFlow::ArgumentNode pathArgument;
|
||||
|
||||
DefaultFileSystemAccess() {
|
||||
sinkNode(pathArgument, "path-injection") and
|
||||
this = pathArgument.getCall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
not pathArgument instanceof DataFlow::ImplicitVarargsSlice and
|
||||
result = pathArgument
|
||||
or
|
||||
pathArgument instanceof DataFlow::ImplicitVarargsSlice and
|
||||
result = this.getAnImplicitVarargsArgument()
|
||||
}
|
||||
}
|
||||
|
||||
/** A function that escapes meta-characters to prevent injection attacks. */
|
||||
class EscapeFunction extends Function instanceof EscapeFunction::Range {
|
||||
/**
|
||||
|
||||
@@ -15,9 +15,11 @@ module Afero {
|
||||
string aferoPackage() { result = package("github.com/spf13/afero", "") }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `FileSystemAccess::Range` instead.
|
||||
*
|
||||
* The File system access sinks of [afero](https://github.com/spf13/afero) framework methods
|
||||
*/
|
||||
class AferoSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
deprecated class AferoSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
AferoSystemAccess() {
|
||||
exists(Method m |
|
||||
m.hasQualifiedName(aferoPackage(), "HttpFs",
|
||||
|
||||
@@ -173,33 +173,6 @@ module Beego {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The File system access sinks
|
||||
*/
|
||||
private class FsOperations extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
int pathArg;
|
||||
|
||||
FsOperations() {
|
||||
this.getTarget().hasQualifiedName(packagePath(), "Walk") and pathArg = 1
|
||||
or
|
||||
exists(Method m | this = m.getACall() |
|
||||
m.hasQualifiedName(packagePath(), "FileSystem", "Open") and pathArg = 0
|
||||
or
|
||||
m.hasQualifiedName(packagePath(), "Controller", "SaveToFile") and pathArg = 1
|
||||
or
|
||||
m.hasQualifiedName(contextPackagePath(), "BeegoOutput", "Download") and
|
||||
pathArg = 0
|
||||
or
|
||||
// SaveToFileWithBuffer only available in v2
|
||||
m.hasQualifiedName("github.com/beego/beego/v2/server/web", "Controller",
|
||||
"SaveToFileWithBuffer") and
|
||||
pathArg = 1
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getArgument(pathArg) }
|
||||
}
|
||||
|
||||
private class RedirectMethods extends Http::Redirect::Range, DataFlow::CallNode {
|
||||
string className;
|
||||
|
||||
|
||||
@@ -70,9 +70,11 @@ private module Echo {
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `FileSystemAccess::Range` instead.
|
||||
*
|
||||
* The File system access sinks
|
||||
*/
|
||||
class FsOperations extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
deprecated class FsOperations extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
FsOperations() {
|
||||
exists(Method m |
|
||||
m.hasQualifiedName(packagePath(), "Context", ["Attachment", "File"]) and
|
||||
|
||||
@@ -175,9 +175,11 @@ module Fasthttp {
|
||||
*/
|
||||
module Functions {
|
||||
/**
|
||||
* DEPRECATED: Use `FileSystemAccess::Range` instead.
|
||||
*
|
||||
* A function that doesn't sanitize user-provided file paths.
|
||||
*/
|
||||
class FileSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
deprecated class FileSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
FileSystemAccess() {
|
||||
exists(Function f |
|
||||
f.hasQualifiedName(packagePath(),
|
||||
@@ -399,12 +401,14 @@ module Fasthttp {
|
||||
/**
|
||||
* Provide modeling for fasthttp.Response Type.
|
||||
*/
|
||||
module Response {
|
||||
deprecated module Response {
|
||||
/**
|
||||
* DEPRECATED: Use `FileSystemAccess::Range` instead.
|
||||
*
|
||||
* A Method that sends files from its input.
|
||||
* It does not check the input path against path traversal attacks, So it is a dangerous method.
|
||||
*/
|
||||
class FileSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
deprecated class FileSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
FileSystemAccess() {
|
||||
exists(Method mcn |
|
||||
mcn.hasQualifiedName(packagePath(), "Response", "SendFile") and
|
||||
@@ -477,9 +481,11 @@ module Fasthttp {
|
||||
*/
|
||||
module RequestCtx {
|
||||
/**
|
||||
* DEPRECATED: Use `FileSystemAccess::Range` instead.
|
||||
*
|
||||
* The Methods that don't sanitize user provided file paths.
|
||||
*/
|
||||
class FileSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
deprecated class FileSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
FileSystemAccess() {
|
||||
exists(Method mcn |
|
||||
mcn.hasQualifiedName(packagePath(), "RequestCtx", ["SendFile", "SendFileBytes"]) and
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/**
|
||||
* Provides classes for working the `github.com/gofiber/fiber` package.
|
||||
*/
|
||||
|
||||
import go
|
||||
|
||||
private module Fiber {
|
||||
/** Gets the package name `github.com/gofiber/fiber`. */
|
||||
string packagePath() { result = package("github.com/gofiber/fiber", "") }
|
||||
|
||||
/** Gets the v2 module path `github.com/gofiber/fiber/v2` */
|
||||
string v2modulePath() { result = "github.com/gofiber/fiber/v2" }
|
||||
|
||||
/**
|
||||
* The File system access sinks
|
||||
*/
|
||||
class FsOperations extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
int pathArg;
|
||||
|
||||
FsOperations() {
|
||||
exists(Method m |
|
||||
(
|
||||
m.hasQualifiedName(packagePath(), "Ctx", ["SendFile", "Download"]) and
|
||||
pathArg = 0
|
||||
or
|
||||
m.hasQualifiedName(packagePath(), "Ctx", "SaveFile") and
|
||||
pathArg = 1
|
||||
or
|
||||
m.hasQualifiedName(v2modulePath(), "Ctx", "SaveFileToStorage") and
|
||||
pathArg = 1
|
||||
) and
|
||||
this = m.getACall()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getArgument(pathArg) }
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/**
|
||||
* Provides classes for working with the `github.com/gin-gonic/gin` package.
|
||||
*/
|
||||
|
||||
import go
|
||||
|
||||
private module Gin {
|
||||
/** Gets the package name `github.com/gin-gonic/gin`. */
|
||||
string packagePath() { result = package("github.com/gin-gonic/gin", "") }
|
||||
|
||||
/**
|
||||
* The File system access sinks
|
||||
*/
|
||||
class FsOperations extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
int pathArg;
|
||||
|
||||
FsOperations() {
|
||||
exists(Method m |
|
||||
(
|
||||
m.hasQualifiedName(packagePath(), "Context", ["File", "FileAttachment"]) and
|
||||
pathArg = 0
|
||||
or
|
||||
m.hasQualifiedName(packagePath(), "Context", "SaveUploadedFile") and
|
||||
pathArg = 1
|
||||
) and
|
||||
this = m.getACall()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getArgument(pathArg) }
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/**
|
||||
* Provides classes for working the `github.com/kataras/iris` package.
|
||||
*/
|
||||
|
||||
import go
|
||||
|
||||
private module Iris {
|
||||
/** Gets the v1 module path `github.com/kataras/iris`. */
|
||||
string v1modulePath() { result = "github.com/kataras/iris" }
|
||||
|
||||
/** Gets the v12 module path `github.com/kataras/iris/v12` */
|
||||
string v12modulePath() { result = "github.com/kataras/iris/v12" }
|
||||
|
||||
/** Gets the path for the context package of all versions of beego. */
|
||||
string contextPackagePath() {
|
||||
result = v12contextPackagePath()
|
||||
or
|
||||
result = v1contextPackagePath()
|
||||
}
|
||||
|
||||
/** Gets the path for the context package of beego v12. */
|
||||
string v12contextPackagePath() { result = v12modulePath() + "/context" }
|
||||
|
||||
/** Gets the path for the context package of beego v1. */
|
||||
string v1contextPackagePath() { result = v1modulePath() + "/server/web/context" }
|
||||
|
||||
/**
|
||||
* The File system access sinks
|
||||
*/
|
||||
class FsOperations extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
int pathArg;
|
||||
|
||||
FsOperations() {
|
||||
exists(Method m |
|
||||
(
|
||||
m.hasQualifiedName(contextPackagePath(), "Context",
|
||||
["SendFile", "ServeFile", "SendFileWithRate", "ServeFileWithRate", "UploadFormFiles"]) and
|
||||
pathArg = 0
|
||||
or
|
||||
m.hasQualifiedName(v12contextPackagePath(), "Context", "SaveFormFile") and
|
||||
pathArg = 1
|
||||
) and
|
||||
this = m.getACall()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getArgument(pathArg) }
|
||||
}
|
||||
}
|
||||
@@ -87,20 +87,6 @@ module Revel {
|
||||
override string getAContentType() { result = contentType }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `revel.Controller.RenderFileName` method, which instructs Revel to open a file and return its contents.
|
||||
* We extend FileSystemAccess rather than HTTP::ResponseBody as this will usually mean exposing a user-controlled
|
||||
* file rather than the actual contents being user-controlled.
|
||||
*/
|
||||
private class RenderFileNameCall extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
RenderFileNameCall() {
|
||||
this =
|
||||
any(Method m | m.hasQualifiedName(packagePath(), "Controller", "RenderFileName")).getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getArgument(0) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `revel.Controller.Redirect` method.
|
||||
*
|
||||
|
||||
@@ -24,7 +24,6 @@ import semmle.go.frameworks.stdlib.Html
|
||||
import semmle.go.frameworks.stdlib.HtmlTemplate
|
||||
import semmle.go.frameworks.stdlib.Io
|
||||
import semmle.go.frameworks.stdlib.IoFs
|
||||
import semmle.go.frameworks.stdlib.IoIoutil
|
||||
import semmle.go.frameworks.stdlib.Log
|
||||
import semmle.go.frameworks.stdlib.MimeMultipart
|
||||
import semmle.go.frameworks.stdlib.MimeQuotedprintable
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `io/ioutil` package.
|
||||
*/
|
||||
|
||||
import go
|
||||
|
||||
/** Provides models of commonly used functions in the `io/ioutil` package. */
|
||||
module IoIoutil {
|
||||
private class IoUtilFileSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
IoUtilFileSystemAccess() {
|
||||
exists(string fn | this.getTarget().hasQualifiedName("io/ioutil", fn) |
|
||||
fn = ["ReadDir", "ReadFile", "TempDir", "TempFile", "WriteFile"]
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getAnArgument() }
|
||||
}
|
||||
}
|
||||
@@ -288,9 +288,11 @@ module NetHttp {
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `FileSystemAccess::Range` instead.
|
||||
*
|
||||
* The File system access sinks
|
||||
*/
|
||||
class HttpServeFile extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
deprecated class HttpServeFile extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
HttpServeFile() {
|
||||
exists(Function f |
|
||||
f.hasQualifiedName("net/http", "ServeFile") and
|
||||
|
||||
@@ -6,71 +6,6 @@ import go
|
||||
|
||||
/** Provides models of commonly used functions in the `os` package. */
|
||||
module Os {
|
||||
/**
|
||||
* A call to a function in `os` that accesses the file system.
|
||||
*/
|
||||
private class OsFileSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
int pathidx;
|
||||
|
||||
OsFileSystemAccess() {
|
||||
exists(string fn | this.getTarget().hasQualifiedName("os", fn) |
|
||||
fn = "Chdir" and pathidx = 0
|
||||
or
|
||||
fn = "Chmod" and pathidx = 0
|
||||
or
|
||||
fn = "Chown" and pathidx = 0
|
||||
or
|
||||
fn = "Chtimes" and pathidx = 0
|
||||
or
|
||||
fn = "Create" and pathidx = 0
|
||||
or
|
||||
fn = "Lchown" and pathidx = 0
|
||||
or
|
||||
fn = "Link" and pathidx in [0 .. 1]
|
||||
or
|
||||
fn = "Lstat" and pathidx = 0
|
||||
or
|
||||
fn = "Mkdir" and pathidx = 0
|
||||
or
|
||||
fn = "MkdirAll" and pathidx = 0
|
||||
or
|
||||
fn = "NewFile" and pathidx = 1
|
||||
or
|
||||
fn = "Open" and pathidx = 0
|
||||
or
|
||||
fn = "OpenFile" and pathidx = 0
|
||||
or
|
||||
fn = "Readlink" and pathidx = 0
|
||||
or
|
||||
fn = "Remove" and pathidx = 0
|
||||
or
|
||||
fn = "RemoveAll" and pathidx = 0
|
||||
or
|
||||
fn = "Rename" and pathidx in [0 .. 1]
|
||||
or
|
||||
fn = "Stat" and pathidx = 0
|
||||
or
|
||||
fn = "Symlink" and pathidx in [0 .. 1]
|
||||
or
|
||||
fn = "Truncate" and pathidx = 0
|
||||
or
|
||||
fn = "DirFS" and pathidx = 0
|
||||
or
|
||||
fn = "ReadDir" and pathidx = 0
|
||||
or
|
||||
fn = "ReadFile" and pathidx = 0
|
||||
or
|
||||
fn = "MkdirTemp" and pathidx in [0 .. 1]
|
||||
or
|
||||
fn = "CreateTemp" and pathidx in [0 .. 1]
|
||||
or
|
||||
fn = "WriteFile" and pathidx = 0
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getArgument(pathidx) }
|
||||
}
|
||||
|
||||
/** The `os.Exit` function, which ends the process. */
|
||||
private class Exit extends Function {
|
||||
Exit() { this.hasQualifiedName("os", "Exit") }
|
||||
|
||||
@@ -10,7 +10,6 @@ import go
|
||||
* (SSRF) vulnerabilities.
|
||||
*/
|
||||
module ServerSideRequestForgery {
|
||||
private import semmle.go.frameworks.Gin
|
||||
private import validator
|
||||
private import semmle.go.security.UrlConcatenation
|
||||
private import semmle.go.dataflow.barrierguardutil.RegexpCheck
|
||||
|
||||
@@ -7,18 +7,23 @@
|
||||
| test.go:342:53:342:61 | untrusted | test.go:340:15:340:26 | call to Data | test.go:342:53:342:61 | untrusted | This path depends on a $@. | test.go:340:15:340:26 | call to Data | user-provided value |
|
||||
| test.go:344:23:344:31 | untrusted | test.go:340:15:340:26 | call to Data | test.go:344:23:344:31 | untrusted | This path depends on a $@. | test.go:340:15:340:26 | call to Data | user-provided value |
|
||||
edges
|
||||
| test.go:215:15:215:26 | call to Data | test.go:216:18:216:26 | untrusted | provenance | Src:MaD:2 |
|
||||
| test.go:215:15:215:26 | call to Data | test.go:217:10:217:18 | untrusted | provenance | Src:MaD:2 |
|
||||
| test.go:215:15:215:26 | call to Data | test.go:218:35:218:43 | untrusted | provenance | Src:MaD:2 |
|
||||
| test.go:324:17:324:37 | selection of RequestBody | test.go:324:40:324:43 | &... | provenance | Src:MaD:3 MaD:1 |
|
||||
| test.go:324:40:324:43 | &... | test.go:326:35:326:43 | untrusted | provenance | |
|
||||
| test.go:332:15:332:26 | call to Data | test.go:334:23:334:31 | untrusted | provenance | Src:MaD:2 |
|
||||
| test.go:340:15:340:26 | call to Data | test.go:342:53:342:61 | untrusted | provenance | Src:MaD:2 |
|
||||
| test.go:340:15:340:26 | call to Data | test.go:344:23:344:31 | untrusted | provenance | Src:MaD:2 |
|
||||
| test.go:215:15:215:26 | call to Data | test.go:216:18:216:26 | untrusted | provenance | Src:MaD:3 Sink:MaD:5 |
|
||||
| test.go:215:15:215:26 | call to Data | test.go:217:10:217:18 | untrusted | provenance | Src:MaD:3 Sink:MaD:8 |
|
||||
| test.go:215:15:215:26 | call to Data | test.go:218:35:218:43 | untrusted | provenance | Src:MaD:3 Sink:MaD:6 |
|
||||
| test.go:324:17:324:37 | selection of RequestBody | test.go:324:40:324:43 | &... | provenance | Src:MaD:4 MaD:1 |
|
||||
| test.go:324:40:324:43 | &... | test.go:326:35:326:43 | untrusted | provenance | Sink:MaD:6 |
|
||||
| test.go:332:15:332:26 | call to Data | test.go:334:23:334:31 | untrusted | provenance | Src:MaD:3 Sink:MaD:2 |
|
||||
| test.go:340:15:340:26 | call to Data | test.go:342:53:342:61 | untrusted | provenance | Src:MaD:3 Sink:MaD:7 |
|
||||
| test.go:340:15:340:26 | call to Data | test.go:344:23:344:31 | untrusted | provenance | Src:MaD:3 Sink:MaD:2 |
|
||||
models
|
||||
| 1 | Summary: encoding/json; ; false; Unmarshal; ; ; Argument[0]; Argument[1]; taint; manual |
|
||||
| 2 | Source: group:beego-context; BeegoInput; true; Data; ; ; ReturnValue[0]; remote; manual |
|
||||
| 3 | Source: group:beego-context; BeegoInput; true; RequestBody; ; ; ; remote; manual |
|
||||
| 2 | Sink: group:beego-context; BeegoOutput; false; Download; ; ; Argument[0]; path-injection; manual |
|
||||
| 3 | Source: group:beego-context; BeegoInput; true; Data; ; ; ReturnValue[0]; remote; manual |
|
||||
| 4 | Source: group:beego-context; BeegoInput; true; RequestBody; ; ; ; remote; manual |
|
||||
| 5 | Sink: group:beego; ; false; Walk; ; ; Argument[1]; path-injection; manual |
|
||||
| 6 | Sink: group:beego; Controller; false; SaveToFile; ; ; Argument[1]; path-injection; manual |
|
||||
| 7 | Sink: group:beego; Controller; false; SaveToFileWithBuffer; ; ; Argument[1]; path-injection; manual |
|
||||
| 8 | Sink: group:beego; FileSystem; false; Open; ; ; Argument[0]; path-injection; manual |
|
||||
nodes
|
||||
| test.go:215:15:215:26 | call to Data | semmle.label | call to Data |
|
||||
| test.go:216:18:216:26 | untrusted | semmle.label | untrusted |
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
| test.go:222:17:222:24 | filepath | test.go:221:15:221:38 | call to QueryParam | test.go:222:17:222:24 | filepath | This path depends on a $@. | test.go:221:15:221:38 | call to QueryParam | user-provided value |
|
||||
| test.go:226:23:226:30 | filepath | test.go:225:15:225:38 | call to QueryParam | test.go:226:23:226:30 | filepath | This path depends on a $@. | test.go:225:15:225:38 | call to QueryParam | user-provided value |
|
||||
edges
|
||||
| test.go:221:15:221:38 | call to QueryParam | test.go:222:17:222:24 | filepath | provenance | Src:MaD:1 |
|
||||
| test.go:225:15:225:38 | call to QueryParam | test.go:226:23:226:30 | filepath | provenance | Src:MaD:1 |
|
||||
| test.go:221:15:221:38 | call to QueryParam | test.go:222:17:222:24 | filepath | provenance | Src:MaD:3 Sink:MaD:2 |
|
||||
| test.go:225:15:225:38 | call to QueryParam | test.go:226:23:226:30 | filepath | provenance | Src:MaD:3 Sink:MaD:1 |
|
||||
models
|
||||
| 1 | Source: github.com/labstack/echo; Context; true; QueryParam; ; ; ReturnValue[0]; remote; manual |
|
||||
| 1 | Sink: github.com/labstack/echo; Context; false; Attachment; ; ; Argument[0]; path-injection; manual |
|
||||
| 2 | Sink: github.com/labstack/echo; Context; false; File; ; ; Argument[0]; path-injection; manual |
|
||||
| 3 | Source: github.com/labstack/echo; Context; true; QueryParam; ; ; ReturnValue[0]; remote; manual |
|
||||
nodes
|
||||
| test.go:221:15:221:38 | call to QueryParam | semmle.label | call to QueryParam |
|
||||
| test.go:222:17:222:24 | filepath | semmle.label | filepath |
|
||||
|
||||
@@ -4,12 +4,15 @@
|
||||
| Gin.go:27:20:27:27 | filepath | Gin.go:24:15:24:33 | call to Query | Gin.go:27:20:27:27 | filepath | This path depends on a $@. | Gin.go:24:15:24:33 | call to Query | user-provided value |
|
||||
| Gin.go:29:32:29:39 | filepath | Gin.go:24:15:24:33 | call to Query | Gin.go:29:32:29:39 | filepath | This path depends on a $@. | Gin.go:24:15:24:33 | call to Query | user-provided value |
|
||||
edges
|
||||
| Gin.go:24:15:24:33 | call to Query | Gin.go:25:10:25:17 | filepath | provenance | Src:MaD:1 |
|
||||
| Gin.go:24:15:24:33 | call to Query | Gin.go:26:39:26:46 | filepath | provenance | Src:MaD:1 |
|
||||
| Gin.go:24:15:24:33 | call to Query | Gin.go:27:20:27:27 | filepath | provenance | Src:MaD:1 |
|
||||
| Gin.go:24:15:24:33 | call to Query | Gin.go:29:32:29:39 | filepath | provenance | Src:MaD:1 |
|
||||
| Gin.go:24:15:24:33 | call to Query | Gin.go:25:10:25:17 | filepath | provenance | Src:MaD:4 Sink:MaD:1 |
|
||||
| Gin.go:24:15:24:33 | call to Query | Gin.go:26:39:26:46 | filepath | provenance | Src:MaD:4 |
|
||||
| Gin.go:24:15:24:33 | call to Query | Gin.go:27:20:27:27 | filepath | provenance | Src:MaD:4 Sink:MaD:2 |
|
||||
| Gin.go:24:15:24:33 | call to Query | Gin.go:29:32:29:39 | filepath | provenance | Src:MaD:4 Sink:MaD:3 |
|
||||
models
|
||||
| 1 | Source: github.com/gin-gonic/gin; Context; true; Query; ; ; ReturnValue; remote; manual |
|
||||
| 1 | Sink: github.com/gin-gonic/gin; Context; false; File; ; ; Argument[0]; path-injection; manual |
|
||||
| 2 | Sink: github.com/gin-gonic/gin; Context; false; FileAttachment; ; ; Argument[0]; path-injection; manual |
|
||||
| 3 | Sink: github.com/gin-gonic/gin; Context; false; SaveUploadedFile; ; ; Argument[1]; path-injection; manual |
|
||||
| 4 | Source: github.com/gin-gonic/gin; Context; true; Query; ; ; ReturnValue; remote; manual |
|
||||
nodes
|
||||
| Gin.go:24:15:24:33 | call to Query | semmle.label | call to Query |
|
||||
| Gin.go:25:10:25:17 | filepath | semmle.label | filepath |
|
||||
|
||||
Reference in New Issue
Block a user