diff --git a/ql/src/experimental/CWE-327/WeakCryptoAlgorithmCustomizations.qll b/ql/src/experimental/CWE-327/WeakCryptoAlgorithmCustomizations.qll index 81bd15a92f3..7348d8afb8c 100644 --- a/ql/src/experimental/CWE-327/WeakCryptoAlgorithmCustomizations.qll +++ b/ql/src/experimental/CWE-327/WeakCryptoAlgorithmCustomizations.qll @@ -8,6 +8,11 @@ import go private import semmle.go.security.SensitiveActions private import CryptoLibraries +/** + * Provides default sources, sinks and sanitizers for reasoning about + * sensitive information in weak cryptographic algorithms, + * as well as extension points for adding your own. + */ module WeakCryptoAlgorithm { /** * A data flow source for sensitive information in weak cryptographic algorithms. diff --git a/ql/src/semmle/go/Expr.qll b/ql/src/semmle/go/Expr.qll index a2bc9b21cba..3d2cf956c11 100644 --- a/ql/src/semmle/go/Expr.qll +++ b/ql/src/semmle/go/Expr.qll @@ -344,6 +344,7 @@ class RuneLit = CharLit; class StringLit extends @stringlit, BasicLit { override string getAPrimaryQlClass() { result = "StringLit" } + /** Holds if this string literal is a raw string literal. */ predicate isRaw() { this.getText().matches("`%`") } } diff --git a/ql/src/semmle/go/frameworks/Beego.qll b/ql/src/semmle/go/frameworks/Beego.qll index 1184938c347..bff7d27fb96 100644 --- a/ql/src/semmle/go/frameworks/Beego.qll +++ b/ql/src/semmle/go/frameworks/Beego.qll @@ -7,6 +7,10 @@ import go import semmle.go.security.Xss private import semmle.go.security.SafeUrlFlowCustomizations +/** + * Provides classes for working with untrusted flow sources, sinks and taint propagators + * from the [Beego](`github.com/beego/beego`) package. + */ module Beego { /** Gets the module path `github.com/astaxie/beego` or `github.com/beego/beego`. */ string modulePath() { result = ["github.com/astaxie/beego", "github.com/beego/beego"] } diff --git a/ql/src/semmle/go/frameworks/BeegoOrm.qll b/ql/src/semmle/go/frameworks/BeegoOrm.qll index cec8783afa5..657f89d59b2 100644 --- a/ql/src/semmle/go/frameworks/BeegoOrm.qll +++ b/ql/src/semmle/go/frameworks/BeegoOrm.qll @@ -6,6 +6,10 @@ import go private import semmle.go.security.StoredXssCustomizations +/** + * Provides classes for working with untrusted flow sources, sinks and taint propagators + * from the [Beego ORM](`github.com/astaxie/beego/orm`) subpackage. + */ module BeegoOrm { /** Gets the package name `github.com/astaxie/beego/orm`. */ string packagePath() { result = package("github.com/astaxie/beego", "orm") } diff --git a/ql/src/semmle/go/frameworks/GoRestfulHttp.qll b/ql/src/semmle/go/frameworks/GoRestfulHttp.qll index 82163bce619..ddaf4dde544 100644 --- a/ql/src/semmle/go/frameworks/GoRestfulHttp.qll +++ b/ql/src/semmle/go/frameworks/GoRestfulHttp.qll @@ -1,3 +1,7 @@ +/** + * Provides models of the [go-restful library](https://github.com/emicklei/go-restful). + */ + import go /** diff --git a/ql/src/semmle/go/frameworks/SQL.qll b/ql/src/semmle/go/frameworks/SQL.qll index 71050478b42..f626fe097ca 100644 --- a/ql/src/semmle/go/frameworks/SQL.qll +++ b/ql/src/semmle/go/frameworks/SQL.qll @@ -215,6 +215,9 @@ module SQL { } } +/** + * Provides classes for working with the [GORM](https://gorm.io/) package. + */ module Gorm { /** Gets the package name for Gorm. */ string packagePath() { diff --git a/ql/src/semmle/go/frameworks/SystemCommandExecutors.qll b/ql/src/semmle/go/frameworks/SystemCommandExecutors.qll index 9c16971a113..b97dd48945a 100644 --- a/ql/src/semmle/go/frameworks/SystemCommandExecutors.qll +++ b/ql/src/semmle/go/frameworks/SystemCommandExecutors.qll @@ -77,6 +77,10 @@ private class GoShCommandExecution extends SystemCommandExecution::Range, DataFl override DataFlow::Node getCommandName() { result = this.getArgument(0) } } +/** + * Provides classes for working with the + * [golang.org/x/crypto/ssh](https://pkg.go.dev/golang.org/x/crypto/ssh) package. + */ module CryptoSsh { /** Gets the package path `golang.org/x/crypto/ssh`. */ string packagePath() { result = package("golang.org/x/crypto", "ssh") } diff --git a/ql/src/semmle/go/frameworks/WebSocket.qll b/ql/src/semmle/go/frameworks/WebSocket.qll index 96e9d52e30e..55f36709a5c 100644 --- a/ql/src/semmle/go/frameworks/WebSocket.qll +++ b/ql/src/semmle/go/frameworks/WebSocket.qll @@ -298,21 +298,36 @@ module WebSocketReader { } } +/** + * Provides classes for working with the [Gorilla WebSocket](https://github.com/gorilla/websocket) + * package. + */ module GorillaWebsocket { /** Gets the package name `github.com/gorilla/websocket`. */ string packagePath() { result = package("github.com/gorilla", "websocket") } } +/** + * Provides classes for working with the + * [golang.org/x/net/websocket](https://pkg.go.dev/golang.org/x/net/websocket) package. + */ module GolangOrgXNetWebsocket { /** Gets the package name `golang.org/x/net/websocket`. */ string packagePath() { result = package("golang.org/x/net", "websocket") } } +/** + * Provides classes for working with the [nhooyr.io/websocket](http://nhooyr.io/websocket) + * package. + */ module NhooyrWebSocket { /** Gets the package name `nhooyr.io/websocket/`. */ string packagePath() { result = package("nhooyr.io/websocket", "") } } +/** + * Provides classes for working with the [ws](https://github.com/gobwas/ws) package. + */ module GobwasWs { /** Gets the package name `github.com/gobwas/ws`. */ string packagePath() { result = package("github.com/gobwas/ws", "") } diff --git a/ql/src/semmle/go/frameworks/XPath.qll b/ql/src/semmle/go/frameworks/XPath.qll index f024569fb75..896007f4641 100644 --- a/ql/src/semmle/go/frameworks/XPath.qll +++ b/ql/src/semmle/go/frameworks/XPath.qll @@ -189,6 +189,9 @@ module XPath { } } +/** + * Provides classes for working with the [xmlpath](https://gopkg.in/xmlpath.v2) package. + */ module XmlPath { /** Gets the package name `github.com/go-xmlpath/xmlpath` or `gopkg.in/xmlpath`. */ string packagePath() { diff --git a/ql/src/semmle/go/security/CommandInjection.qll b/ql/src/semmle/go/security/CommandInjection.qll index 13963a2c546..6f36760b3b4 100644 --- a/ql/src/semmle/go/security/CommandInjection.qll +++ b/ql/src/semmle/go/security/CommandInjection.qll @@ -17,7 +17,8 @@ module CommandInjection { import CommandInjectionCustomizations::CommandInjection /** - * A taint-tracking configuration for reasoning about command-injection vulnerabilities. + * A taint-tracking configuration for reasoning about command-injection vulnerabilities + * with sinks which are not sanitized by `--`. */ class Configuration extends TaintTracking::Configuration { Configuration() { this = "CommandInjection" } @@ -77,6 +78,10 @@ module CommandInjection { } } + /** + * A taint-tracking configuration for reasoning about command-injection vulnerabilities + * with sinks which are sanitized by `--`. + */ class DoubleDashSanitizingConfiguration extends TaintTracking::Configuration { DoubleDashSanitizingConfiguration() { this = "CommandInjectionWithDoubleDashSanitizer" } diff --git a/ql/src/semmle/go/security/InsecureRandomnessCustomizations.qll b/ql/src/semmle/go/security/InsecureRandomnessCustomizations.qll index 57abb3aa185..db8ff731fbc 100644 --- a/ql/src/semmle/go/security/InsecureRandomnessCustomizations.qll +++ b/ql/src/semmle/go/security/InsecureRandomnessCustomizations.qll @@ -5,6 +5,10 @@ import go +/** + * Provides default sources, sinks and sanitizers for reasoning about random values that are + * not cryptographically secure, as well as extension points for adding your own. + */ module InsecureRandomness { /** * A data flow source for insufficient random sources @@ -32,6 +36,10 @@ module InsecureRandomness { InsecureRandomSource() { this.getTarget().getPackage().getPath() = "math/rand" } } + /** + * Gets an interface outside of the `crypto` package which is the same as an + * interface in the `crypto` package. + */ string nonCryptoInterface() { result = ["io.Writer", "io.Reader", "sync.Mutex", "net.Listener"] } /** @@ -47,8 +55,11 @@ module InsecureRandomness { pkg.regexpMatch("crypto/.*") and not pkg = getAHashPkg() and not (pkg = "crypto/rand" and name = "Read") and - not (pkg = "crypto/cipher" and name = ["Read", "Write"]) and // crypto/cipher APIs for reading/writing encrypted streams - not fn.hasQualifiedName(nonCryptoInterface(), _) and // some interfaces in crypto are the same as interfaces elsewhere, e.g. tls.listener is the same as net.Listener + // `crypto/cipher` APIs for reading/writing encrypted streams + not (pkg = "crypto/cipher" and name = ["Read", "Write"]) and + // Some interfaces in the `crypto` package are the same as interfaces + // elsewhere, e.g. tls.listener is the same as net.Listener + not fn.hasQualifiedName(nonCryptoInterface(), _) and this = fn.getACall().getAnArgument() ) } @@ -71,6 +82,7 @@ module InsecureRandomness { override string getKind() { result = "a password-related function" } } + /** Gets a package that implements hash algorithms. */ bindingset[result] private string getAHashPkg() { result.regexpMatch("crypto/(md5|sha(1|256|512)|rand)") }