From 5cd3627dc60b65763e08e0ff15078d526e1db91f Mon Sep 17 00:00:00 2001 From: eikendev Date: Sun, 13 Feb 2022 15:06:54 +0100 Subject: [PATCH 01/17] Add scans with gosec --- Makefile | 2 ++ cmd/pushbits/main.go | 5 ++++- internal/api/application.go | 7 +++++-- internal/api/user.go | 6 ++++++ internal/authentication/credentials/hibp.go | 4 ++-- internal/database/database.go | 20 ++++++++++++++++---- internal/dispatcher/dispatcher.go | 6 +++++- internal/runner/runner.go | 9 +++++++-- 8 files changed, 47 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 4567096..de41680 100644 --- a/Makefile +++ b/Makefile @@ -13,10 +13,12 @@ test: gocyclo -over 10 $(shell find . -iname '*.go' -type f) staticcheck ./... go test -v -cover ./... + gosec -exclude-dir=tests ./... .PHONY: setup setup: go install github.com/fzipp/gocyclo/cmd/gocyclo@latest + go install github.com/securego/gosec/v2/cmd/gosec@latest go install github.com/swaggo/swag/cmd/swag@latest go install honnef.co/go/tools/cmd/staticcheck@latest diff --git a/cmd/pushbits/main.go b/cmd/pushbits/main.go index 254065e..30d9c50 100644 --- a/cmd/pushbits/main.go +++ b/cmd/pushbits/main.go @@ -77,5 +77,8 @@ func main() { engine := router.Create(c.Debug, cm, db, dp) - runner.Run(engine, c.HTTP.ListenAddress, c.HTTP.Port) + err = runner.Run(engine, c.HTTP.ListenAddress, c.HTTP.Port) + if err != nil { + log.Fatal(err) + } } diff --git a/internal/api/application.go b/internal/api/application.go index 9914924..341b588 100644 --- a/internal/api/application.go +++ b/internal/api/application.go @@ -35,7 +35,11 @@ func (h *ApplicationHandler) registerApplication(ctx *gin.Context, a *model.Appl } a.MatrixID = channelID - h.DB.UpdateApplication(a) + + err = h.DB.UpdateApplication(a) + if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success { + return err + } return nil } @@ -55,7 +59,6 @@ func (h *ApplicationHandler) createApplication(ctx *gin.Context, u *model.User, if err := h.registerApplication(ctx, &application, u); err != nil { err := h.DB.DeleteApplication(&application) - if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success { log.Printf("Cannot delete application with ID %d.", application.ID) } diff --git a/internal/api/user.go b/internal/api/user.go index 385c443..3421459 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -44,6 +44,8 @@ func (h *UserHandler) deleteApplications(ctx *gin.Context, u *model.User) error } for _, application := range applications { + application := application // See https://stackoverflow.com/a/68247837 + if err := h.AH.deleteApplication(ctx, &application, u); err != nil { return err } @@ -59,6 +61,8 @@ func (h *UserHandler) updateChannels(ctx *gin.Context, u *model.User, matrixID s } for _, application := range applications { + application := application // See https://stackoverflow.com/a/68247837 + err := h.DP.DeregisterApplication(&application, u) if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success { return err @@ -68,6 +72,8 @@ func (h *UserHandler) updateChannels(ctx *gin.Context, u *model.User, matrixID s u.MatrixID = matrixID for _, application := range applications { + application := application // See https://stackoverflow.com/a/68247837 + err := h.AH.registerApplication(ctx, &application, u) if err != nil { return err diff --git a/internal/authentication/credentials/hibp.go b/internal/authentication/credentials/hibp.go index 81680a8..33bd131 100644 --- a/internal/authentication/credentials/hibp.go +++ b/internal/authentication/credentials/hibp.go @@ -1,7 +1,7 @@ package credentials import ( - "crypto/sha1" + "crypto/sha1" //#nosec G505 -- False positive, see the use below. "fmt" "io/ioutil" "log" @@ -21,7 +21,7 @@ func IsPasswordPwned(password string) (bool, error) { return true, nil } - hash := sha1.Sum([]byte(password)) + hash := sha1.Sum([]byte(password)) //#nosec G401 -- False positive, only the first 5 bytes are transmitted. hashStr := fmt.Sprintf("%X", hash) lookup := hashStr[0:5] match := hashStr[5:] diff --git a/internal/database/database.go b/internal/database/database.go index c7f52ff..886e042 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -24,8 +24,10 @@ type Database struct { } func createFileDir(file string) { - if _, err := os.Stat(filepath.Dir(file)); os.IsNotExist(err) { - if err := os.MkdirAll(filepath.Dir(file), 0775); err != nil { + dir := filepath.Dir(file) + + if _, err := os.Stat(dir); os.IsNotExist(err) { + if err := os.MkdirAll(dir, 0750); err != nil { panic(err) } } @@ -67,14 +69,20 @@ func Create(cm *credentials.Manager, dialect, connection string) (*Database, err sql.SetConnMaxLifetime(9 * time.Minute) } - db.AutoMigrate(&model.User{}, &model.Application{}) + err = db.AutoMigrate(&model.User{}, &model.Application{}) + if err != nil { + return nil, err + } return &Database{gormdb: db, sqldb: sql, credentialsManager: cm}, nil } // Close closes the database connection. func (d *Database) Close() { - d.sqldb.Close() + err := d.sqldb.Close() + if err != nil { + log.Printf("Error while closing database: %s", err) + } } // Populate fills the database with initial information like the admin user. @@ -111,12 +119,16 @@ func (d *Database) RepairChannels(dp Dispatcher) error { } for _, user := range users { + user := user // See https://stackoverflow.com/a/68247837 + applications, err := d.GetApplications(&user) if err != nil { return err } for _, application := range applications { + application := application // See https://stackoverflow.com/a/68247837 + if err := dp.UpdateApplication(&application); err != nil { return err } diff --git a/internal/dispatcher/dispatcher.go b/internal/dispatcher/dispatcher.go index 735c072..caa4329 100644 --- a/internal/dispatcher/dispatcher.go +++ b/internal/dispatcher/dispatcher.go @@ -44,7 +44,11 @@ func Create(homeserver, username, password string, formatting configuration.Form func (d *Dispatcher) Close() { log.Printf("Logging out.") - d.client.Logout() + _, err := d.client.Logout() + if err != nil { + log.Printf("Error while logging out: %s", err) + } + d.client.ClearCredentials() log.Printf("Successfully logged out.") diff --git a/internal/runner/runner.go b/internal/runner/runner.go index 2043179..911f778 100644 --- a/internal/runner/runner.go +++ b/internal/runner/runner.go @@ -7,6 +7,11 @@ import ( ) // Run starts the Gin engine. -func Run(engine *gin.Engine, address string, port int) { - engine.Run(fmt.Sprintf("%s:%d", address, port)) +func Run(engine *gin.Engine, address string, port int) error { + err := engine.Run(fmt.Sprintf("%s:%d", address, port)) + if err != nil { + return err + } + + return nil } From 23e64b838076070b48ba3e9f12570b419f41406d Mon Sep 17 00:00:00 2001 From: eikendev Date: Sun, 13 Feb 2022 15:54:57 +0100 Subject: [PATCH 02/17] Add scans with Semgrep --- .envrc | 1 + Makefile | 2 + internal/api/user.go | 6 +- internal/authentication/credentials/hibp.go | 1 + internal/database/database.go | 1 + poetry.lock | 439 ++++++++++++++++++ pyproject.toml | 11 + .../go/aws-lambda/security/database-sqli.yaml | 51 ++ ...dler-assignment-from-multiple-sources.yaml | 57 +++ .../session-cookie-missing-httponly.yaml | 33 ++ .../audit/session-cookie-missing-secure.yaml | 32 ++ .../grpc-client-insecure-connection.yaml | 26 ++ .../grpc-server-insecure-connection.yaml | 41 ++ .../security/audit/jwt-parse-unverified.yaml | 22 + .../go/jwt-go/security/jwt-none-alg.yaml | 26 ++ tests/semgrep/go/jwt-go/security/jwt.yaml | 19 + .../channel-guarded-with-mutex.yaml | 22 + .../lang/best-practice/hidden-goroutine.yaml | 27 ++ .../go/lang/correctness/looppointer.yaml | 29 ++ .../lang/correctness/overflow/overflow.yaml | 39 ++ .../permissions/file_permission.yaml | 25 + .../lang/correctness/use-filepath-join.yaml | 16 + .../go/lang/correctness/useless-eqeq.yaml | 31 ++ .../lang/maintainability/useless-ifelse.yaml | 33 ++ .../security/audit/crypto/bad_imports.yaml | 48 ++ .../security/audit/crypto/insecure_ssh.yaml | 23 + .../security/audit/crypto/math_random.yaml | 32 ++ .../audit/crypto/missing-ssl-minversion.yaml | 28 ++ .../go/lang/security/audit/crypto/ssl.yaml | 23 + .../go/lang/security/audit/crypto/tls.yaml | 45 ++ .../audit/crypto/use_of_weak_crypto.yaml | 73 +++ .../audit/crypto/use_of_weak_rsa_key.yaml | 24 + .../audit/dangerous-command-write.yaml | 35 ++ .../security/audit/dangerous-exec-cmd.yaml | 76 +++ .../audit/dangerous-exec-command.yaml | 47 ++ .../audit/dangerous-syscall-exec.yaml | 88 ++++ .../database/string-formatted-query.yaml | 155 +++++++ .../security/audit/md5-used-as-password.yaml | 35 ++ .../go/lang/security/audit/net/bind_all.yaml | 21 + .../audit/net/cookie-missing-httponly.yaml | 34 ++ .../audit/net/cookie-missing-secure.yaml | 33 ++ .../net/dynamic-httptrace-clienttrace.yaml | 32 ++ .../audit/net/formatted-template-string.yaml | 47 ++ .../go/lang/security/audit/net/pprof.yaml | 35 ++ .../audit/net/unescaped-data-in-htmlattr.yaml | 47 ++ .../audit/net/unescaped-data-in-js.yaml | 46 ++ .../audit/net/unescaped-data-in-url.yaml | 48 ++ .../go/lang/security/audit/net/use-tls.yaml | 18 + ...p-xss-using-responsewriter-and-printf.yaml | 61 +++ .../lang/security/audit/reflect-makefunc.yaml | 18 + .../lang/security/audit/sqli/gosql-sqli.yaml | 52 +++ .../lang/security/audit/sqli/pg-orm-sqli.yaml | 55 +++ .../go/lang/security/audit/sqli/pg-sqli.yaml | 55 +++ .../go/lang/security/audit/sqli/pgx-sqli.yaml | 59 +++ .../audit/unsafe-reflect-by-name.yaml | 34 ++ .../go/lang/security/audit/unsafe.yaml | 17 + .../audit/xss/import-text-template.yaml | 21 + .../no-direct-write-to-responsewriter.yaml | 40 ++ .../xss/no-fprintf-to-responsewriter.yaml | 33 ++ .../audit/xss/no-interpolation-in-tag.yaml | 24 + .../no-interpolation-js-template-string.yaml | 28 ++ .../no-io-writestring-to-responsewriter.yaml | 34 ++ .../xss/no-printf-in-responsewriter.yaml | 33 ++ .../xss/template-html-does-not-escape.yaml | 34 ++ tests/semgrep/go/lang/security/bad_tmp.yaml | 15 + .../go/lang/security/decompression_bomb.yaml | 59 +++ .../lang/security/filepath-clean-misuse.yaml | 41 ++ .../security/injection/raw-html-format.yaml | 47 ++ .../injection/tainted-sql-string.yaml | 50 ++ .../security/injection/tainted-url-host.yaml | 46 ++ tests/semgrep/go/lang/security/zip.yaml | 20 + .../security/audit/dangerous-execution.yaml | 24 + .../go/template/security/insecure-types.yaml | 26 ++ 73 files changed, 3006 insertions(+), 3 deletions(-) create mode 100644 .envrc create mode 100644 poetry.lock create mode 100644 pyproject.toml create mode 100644 tests/semgrep/go/aws-lambda/security/database-sqli.yaml create mode 100644 tests/semgrep/go/gorilla/security/audit/handler-assignment-from-multiple-sources.yaml create mode 100644 tests/semgrep/go/gorilla/security/audit/session-cookie-missing-httponly.yaml create mode 100644 tests/semgrep/go/gorilla/security/audit/session-cookie-missing-secure.yaml create mode 100644 tests/semgrep/go/grpc/security/grpc-client-insecure-connection.yaml create mode 100644 tests/semgrep/go/grpc/security/grpc-server-insecure-connection.yaml create mode 100644 tests/semgrep/go/jwt-go/security/audit/jwt-parse-unverified.yaml create mode 100644 tests/semgrep/go/jwt-go/security/jwt-none-alg.yaml create mode 100644 tests/semgrep/go/jwt-go/security/jwt.yaml create mode 100644 tests/semgrep/go/lang/best-practice/channel-guarded-with-mutex.yaml create mode 100644 tests/semgrep/go/lang/best-practice/hidden-goroutine.yaml create mode 100644 tests/semgrep/go/lang/correctness/looppointer.yaml create mode 100644 tests/semgrep/go/lang/correctness/overflow/overflow.yaml create mode 100644 tests/semgrep/go/lang/correctness/permissions/file_permission.yaml create mode 100644 tests/semgrep/go/lang/correctness/use-filepath-join.yaml create mode 100644 tests/semgrep/go/lang/correctness/useless-eqeq.yaml create mode 100644 tests/semgrep/go/lang/maintainability/useless-ifelse.yaml create mode 100644 tests/semgrep/go/lang/security/audit/crypto/bad_imports.yaml create mode 100644 tests/semgrep/go/lang/security/audit/crypto/insecure_ssh.yaml create mode 100644 tests/semgrep/go/lang/security/audit/crypto/math_random.yaml create mode 100644 tests/semgrep/go/lang/security/audit/crypto/missing-ssl-minversion.yaml create mode 100644 tests/semgrep/go/lang/security/audit/crypto/ssl.yaml create mode 100644 tests/semgrep/go/lang/security/audit/crypto/tls.yaml create mode 100644 tests/semgrep/go/lang/security/audit/crypto/use_of_weak_crypto.yaml create mode 100644 tests/semgrep/go/lang/security/audit/crypto/use_of_weak_rsa_key.yaml create mode 100644 tests/semgrep/go/lang/security/audit/dangerous-command-write.yaml create mode 100644 tests/semgrep/go/lang/security/audit/dangerous-exec-cmd.yaml create mode 100644 tests/semgrep/go/lang/security/audit/dangerous-exec-command.yaml create mode 100644 tests/semgrep/go/lang/security/audit/dangerous-syscall-exec.yaml create mode 100644 tests/semgrep/go/lang/security/audit/database/string-formatted-query.yaml create mode 100644 tests/semgrep/go/lang/security/audit/md5-used-as-password.yaml create mode 100644 tests/semgrep/go/lang/security/audit/net/bind_all.yaml create mode 100644 tests/semgrep/go/lang/security/audit/net/cookie-missing-httponly.yaml create mode 100644 tests/semgrep/go/lang/security/audit/net/cookie-missing-secure.yaml create mode 100644 tests/semgrep/go/lang/security/audit/net/dynamic-httptrace-clienttrace.yaml create mode 100644 tests/semgrep/go/lang/security/audit/net/formatted-template-string.yaml create mode 100644 tests/semgrep/go/lang/security/audit/net/pprof.yaml create mode 100644 tests/semgrep/go/lang/security/audit/net/unescaped-data-in-htmlattr.yaml create mode 100644 tests/semgrep/go/lang/security/audit/net/unescaped-data-in-js.yaml create mode 100644 tests/semgrep/go/lang/security/audit/net/unescaped-data-in-url.yaml create mode 100644 tests/semgrep/go/lang/security/audit/net/use-tls.yaml create mode 100644 tests/semgrep/go/lang/security/audit/net/wip-xss-using-responsewriter-and-printf.yaml create mode 100644 tests/semgrep/go/lang/security/audit/reflect-makefunc.yaml create mode 100644 tests/semgrep/go/lang/security/audit/sqli/gosql-sqli.yaml create mode 100644 tests/semgrep/go/lang/security/audit/sqli/pg-orm-sqli.yaml create mode 100644 tests/semgrep/go/lang/security/audit/sqli/pg-sqli.yaml create mode 100644 tests/semgrep/go/lang/security/audit/sqli/pgx-sqli.yaml create mode 100644 tests/semgrep/go/lang/security/audit/unsafe-reflect-by-name.yaml create mode 100644 tests/semgrep/go/lang/security/audit/unsafe.yaml create mode 100644 tests/semgrep/go/lang/security/audit/xss/import-text-template.yaml create mode 100644 tests/semgrep/go/lang/security/audit/xss/no-direct-write-to-responsewriter.yaml create mode 100644 tests/semgrep/go/lang/security/audit/xss/no-fprintf-to-responsewriter.yaml create mode 100644 tests/semgrep/go/lang/security/audit/xss/no-interpolation-in-tag.yaml create mode 100644 tests/semgrep/go/lang/security/audit/xss/no-interpolation-js-template-string.yaml create mode 100644 tests/semgrep/go/lang/security/audit/xss/no-io-writestring-to-responsewriter.yaml create mode 100644 tests/semgrep/go/lang/security/audit/xss/no-printf-in-responsewriter.yaml create mode 100644 tests/semgrep/go/lang/security/audit/xss/template-html-does-not-escape.yaml create mode 100644 tests/semgrep/go/lang/security/bad_tmp.yaml create mode 100644 tests/semgrep/go/lang/security/decompression_bomb.yaml create mode 100644 tests/semgrep/go/lang/security/filepath-clean-misuse.yaml create mode 100644 tests/semgrep/go/lang/security/injection/raw-html-format.yaml create mode 100644 tests/semgrep/go/lang/security/injection/tainted-sql-string.yaml create mode 100644 tests/semgrep/go/lang/security/injection/tainted-url-host.yaml create mode 100644 tests/semgrep/go/lang/security/zip.yaml create mode 100644 tests/semgrep/go/otto/security/audit/dangerous-execution.yaml create mode 100644 tests/semgrep/go/template/security/insecure-types.yaml diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..eac69ce --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +layout_poetry diff --git a/Makefile b/Makefile index de41680..6f549ce 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ test: staticcheck ./... go test -v -cover ./... gosec -exclude-dir=tests ./... + semgrep --lang=go --config=tests/semgrep .PHONY: setup setup: @@ -21,6 +22,7 @@ setup: go install github.com/securego/gosec/v2/cmd/gosec@latest go install github.com/swaggo/swag/cmd/swag@latest go install honnef.co/go/tools/cmd/staticcheck@latest + poetry install .PHONY: swag swag: diff --git a/internal/api/user.go b/internal/api/user.go index 3421459..3dca53f 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -175,10 +175,10 @@ func (h *UserHandler) GetUsers(ctx *gin.Context) { return } - var externalUsers []*model.ExternalUser + externalUsers := make([]*model.ExternalUser, len(users)) - for _, user := range users { - externalUsers = append(externalUsers, user.IntoExternalUser()) + for i, user := range users { + externalUsers[i] = user.IntoExternalUser() } ctx.JSON(http.StatusOK, &externalUsers) diff --git a/internal/authentication/credentials/hibp.go b/internal/authentication/credentials/hibp.go index 33bd131..d10f3f2 100644 --- a/internal/authentication/credentials/hibp.go +++ b/internal/authentication/credentials/hibp.go @@ -21,6 +21,7 @@ func IsPasswordPwned(password string) (bool, error) { return true, nil } + // nosemgrep: tests.semgrep.go.lang.security.audit.crypto.insecure-module-used, tests.semgrep.go.lang.security.audit.crypto.use-of-sha1 hash := sha1.Sum([]byte(password)) //#nosec G401 -- False positive, only the first 5 bytes are transmitted. hashStr := fmt.Sprintf("%X", hash) lookup := hashStr[0:5] diff --git a/internal/database/database.go b/internal/database/database.go index 886e042..affe7fd 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -27,6 +27,7 @@ func createFileDir(file string) { dir := filepath.Dir(file) if _, err := os.Stat(dir); os.IsNotExist(err) { + // nosemgrep: tests.semgrep.go.lang.correctness.permissions.incorrect-default-permission if err := os.MkdirAll(dir, 0750); err != nil { panic(err) } diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..bbdf101 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,439 @@ +[[package]] +name = "attrs" +version = "21.4.0" +description = "Classes Without Boilerplate" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.extras] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] +docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] + +[[package]] +name = "bracex" +version = "2.2.1" +description = "Bash style brace expander." +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "certifi" +version = "2021.10.8" +description = "Python package for providing Mozilla's CA Bundle." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "charset-normalizer" +version = "2.0.12" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "dev" +optional = false +python-versions = ">=3.5.0" + +[package.extras] +unicode_backport = ["unicodedata2"] + +[[package]] +name = "click" +version = "8.0.3" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} + +[[package]] +name = "click-option-group" +version = "0.5.3" +description = "Option groups missing in Click" +category = "dev" +optional = false +python-versions = ">=3.6,<4" + +[package.dependencies] +Click = ">=7.0,<9" + +[package.extras] +docs = ["sphinx (>=2.3,<3)", "pallets-sphinx-themes", "m2r"] +tests = ["coverage (<6)", "pytest", "pytest-cov", "coveralls"] + +[[package]] +name = "colorama" +version = "0.4.4" +description = "Cross-platform colored terminal text." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "idna" +version = "3.3" +description = "Internationalized Domain Names in Applications (IDNA)" +category = "dev" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "importlib-metadata" +version = "4.11.0" +description = "Read metadata from Python packages" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} +zipp = ">=0.5" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +perf = ["ipython"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] + +[[package]] +name = "importlib-resources" +version = "5.4.0" +description = "Read resources from Python packages" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-black (>=0.3.7)", "pytest-mypy"] + +[[package]] +name = "jsonschema" +version = "4.4.0" +description = "An implementation of JSON Schema validation for Python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +attrs = ">=17.4.0" +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" +typing-extensions = {version = "*", markers = "python_version < \"3.8\""} + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format_nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] + +[[package]] +name = "packaging" +version = "21.3" +description = "Core utilities for Python packages" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" + +[[package]] +name = "peewee" +version = "3.14.8" +description = "a little orm" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "pyparsing" +version = "3.0.7" +description = "Python parsing module" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "pyrsistent" +version = "0.18.1" +description = "Persistent/Functional/Immutable data structures" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "requests" +version = "2.27.1" +description = "Python HTTP for Humans." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} +idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} +urllib3 = ">=1.21.1,<1.27" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] + +[[package]] +name = "ruamel.yaml" +version = "0.17.21" +description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" +category = "dev" +optional = false +python-versions = ">=3" + +[package.dependencies] +"ruamel.yaml.clib" = {version = ">=0.2.6", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.11\""} + +[package.extras] +docs = ["ryd"] +jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] + +[[package]] +name = "ruamel.yaml.clib" +version = "0.2.6" +description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" +category = "dev" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "semgrep" +version = "0.82.0" +description = "Lightweight static analysis for many languages. Find bug variants with patterns that look like source code." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +attrs = ">=19.3.0" +click = ">=8.0.1" +click-option-group = ">=0.5.3" +colorama = ">=0.4.3" +jsonschema = ">=3.2.0,<5" +packaging = ">=20.4" +peewee = ">=3.14.4,<3.15.0" +requests = ">=2.22.0" +"ruamel.yaml" = ">=0.16.0,<0.18" +tqdm = ">=4.46.1" +wcmatch = "8.3" + +[[package]] +name = "tqdm" +version = "4.62.3" +description = "Fast, Extensible Progress Meter" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["py-make (>=0.1.0)", "twine", "wheel"] +notebook = ["ipywidgets (>=6)"] +telegram = ["requests"] + +[[package]] +name = "typing-extensions" +version = "4.1.0" +description = "Backported and Experimental Type Hints for Python 3.6+" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "urllib3" +version = "1.26.8" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" + +[package.extras] +brotli = ["brotlipy (>=0.6.0)"] +secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + +[[package]] +name = "wcmatch" +version = "8.3" +description = "Wildcard/glob file name matcher." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +bracex = ">=2.1.1" + +[[package]] +name = "zipp" +version = "3.7.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] + +[metadata] +lock-version = "1.1" +python-versions = "^3.7" +content-hash = "792ec3aa3a1641a70a6cd82c2399211c85c8a5cad5522f260c86ef407f8482ce" + +[metadata.files] +attrs = [ + {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, + {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, +] +bracex = [ + {file = "bracex-2.2.1-py3-none-any.whl", hash = "sha256:096c4b788bf492f7af4e90ef8b5bcbfb99759ae3415ea1b83c9d29a5ed8f9a94"}, + {file = "bracex-2.2.1.tar.gz", hash = "sha256:1c8d1296e00ad9a91030ccb4c291f9e4dc7c054f12c707ba3c5ff3e9a81bcd21"}, +] +certifi = [ + {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, + {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, +] +charset-normalizer = [ + {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, + {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, +] +click = [ + {file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"}, + {file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"}, +] +click-option-group = [ + {file = "click-option-group-0.5.3.tar.gz", hash = "sha256:a6e924f3c46b657feb5b72679f7e930f8e5b224b766ab35c91ae4019b4e0615e"}, + {file = "click_option_group-0.5.3-py3-none-any.whl", hash = "sha256:9653a2297357335d7325a1827e71ac1245d91c97d959346a7decabd4a52d5354"}, +] +colorama = [ + {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, + {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, +] +idna = [ + {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, + {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, +] +importlib-metadata = [ + {file = "importlib_metadata-4.11.0-py3-none-any.whl", hash = "sha256:6affcdb3aec542dd98df8211e730bba6c5f2bec8288d47bacacde898f548c9ad"}, + {file = "importlib_metadata-4.11.0.tar.gz", hash = "sha256:9e5e553bbba1843cb4a00823014b907616be46ee503d2b9ba001d214a8da218f"}, +] +importlib-resources = [ + {file = "importlib_resources-5.4.0-py3-none-any.whl", hash = "sha256:33a95faed5fc19b4bc16b29a6eeae248a3fe69dd55d4d229d2b480e23eeaad45"}, + {file = "importlib_resources-5.4.0.tar.gz", hash = "sha256:d756e2f85dd4de2ba89be0b21dba2a3bbec2e871a42a3a16719258a11f87506b"}, +] +jsonschema = [ + {file = "jsonschema-4.4.0-py3-none-any.whl", hash = "sha256:77281a1f71684953ee8b3d488371b162419767973789272434bbc3f29d9c8823"}, + {file = "jsonschema-4.4.0.tar.gz", hash = "sha256:636694eb41b3535ed608fe04129f26542b59ed99808b4f688aa32dcf55317a83"}, +] +packaging = [ + {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, + {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, +] +peewee = [ + {file = "peewee-3.14.8.tar.gz", hash = "sha256:01bd7f734defb08d7a3346a0c0ca7011bc8d0d685934ec0e001b3371d522ec53"}, +] +pyparsing = [ + {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, + {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, +] +pyrsistent = [ + {file = "pyrsistent-0.18.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1"}, + {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26"}, + {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e"}, + {file = "pyrsistent-0.18.1-cp310-cp310-win32.whl", hash = "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6"}, + {file = "pyrsistent-0.18.1-cp310-cp310-win_amd64.whl", hash = "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-win32.whl", hash = "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-win_amd64.whl", hash = "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286"}, + {file = "pyrsistent-0.18.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6"}, + {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec"}, + {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c"}, + {file = "pyrsistent-0.18.1-cp38-cp38-win32.whl", hash = "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca"}, + {file = "pyrsistent-0.18.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a"}, + {file = "pyrsistent-0.18.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5"}, + {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045"}, + {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c"}, + {file = "pyrsistent-0.18.1-cp39-cp39-win32.whl", hash = "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc"}, + {file = "pyrsistent-0.18.1-cp39-cp39-win_amd64.whl", hash = "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07"}, + {file = "pyrsistent-0.18.1.tar.gz", hash = "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96"}, +] +requests = [ + {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, + {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, +] +"ruamel.yaml" = [ + {file = "ruamel.yaml-0.17.21-py3-none-any.whl", hash = "sha256:742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"}, + {file = "ruamel.yaml-0.17.21.tar.gz", hash = "sha256:8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"}, +] +"ruamel.yaml.clib" = [ + {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6e7be2c5bcb297f5b82fee9c665eb2eb7001d1050deaba8471842979293a80b0"}, + {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:221eca6f35076c6ae472a531afa1c223b9c29377e62936f61bc8e6e8bdc5f9e7"}, + {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win32.whl", hash = "sha256:1070ba9dd7f9370d0513d649420c3b362ac2d687fe78c6e888f5b12bf8bc7bee"}, + {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:77df077d32921ad46f34816a9a16e6356d8100374579bc35e15bab5d4e9377de"}, + {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:cfdb9389d888c5b74af297e51ce357b800dd844898af9d4a547ffc143fa56751"}, + {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7b2927e92feb51d830f531de4ccb11b320255ee95e791022555971c466af4527"}, + {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win32.whl", hash = "sha256:ada3f400d9923a190ea8b59c8f60680c4ef8a4b0dfae134d2f2ff68429adfab5"}, + {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win_amd64.whl", hash = "sha256:de9c6b8a1ba52919ae919f3ae96abb72b994dd0350226e28f3686cb4f142165c"}, + {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d67f273097c368265a7b81e152e07fb90ed395df6e552b9fa858c6d2c9f42502"}, + {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:72a2b8b2ff0a627496aad76f37a652bcef400fd861721744201ef1b45199ab78"}, + {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win32.whl", hash = "sha256:9efef4aab5353387b07f6b22ace0867032b900d8e91674b5d8ea9150db5cae94"}, + {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win_amd64.whl", hash = "sha256:846fc8336443106fe23f9b6d6b8c14a53d38cef9a375149d61f99d78782ea468"}, + {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0847201b767447fc33b9c235780d3aa90357d20dd6108b92be544427bea197dd"}, + {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:78988ed190206672da0f5d50c61afef8f67daa718d614377dcd5e3ed85ab4a99"}, + {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win32.whl", hash = "sha256:a49e0161897901d1ac9c4a79984b8410f450565bbad64dbfcbf76152743a0cdb"}, + {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:bf75d28fa071645c529b5474a550a44686821decebdd00e21127ef1fd566eabe"}, + {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a32f8d81ea0c6173ab1b3da956869114cae53ba1e9f72374032e33ba3118c233"}, + {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7f7ecb53ae6848f959db6ae93bdff1740e651809780822270eab111500842a84"}, + {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win32.whl", hash = "sha256:89221ec6d6026f8ae859c09b9718799fea22c0e8da8b766b0b2c9a9ba2db326b"}, + {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:31ea73e564a7b5fbbe8188ab8b334393e06d997914a4e184975348f204790277"}, + {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dc6a613d6c74eef5a14a214d433d06291526145431c3b964f5e16529b1842bed"}, + {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:1866cf2c284a03b9524a5cc00daca56d80057c5ce3cdc86a52020f4c720856f0"}, + {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win32.whl", hash = "sha256:3fb9575a5acd13031c57a62cc7823e5d2ff8bc3835ba4d94b921b4e6ee664104"}, + {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:825d5fccef6da42f3c8eccd4281af399f21c02b32d98e113dbc631ea6a6ecbc7"}, + {file = "ruamel.yaml.clib-0.2.6.tar.gz", hash = "sha256:4ff604ce439abb20794f05613c374759ce10e3595d1867764dd1ae675b85acbd"}, +] +semgrep = [ + {file = "semgrep-0.82.0-cp37.cp38.cp39.py37.py38.py39-none-any.whl", hash = "sha256:1750f2b755ffc7db4690e6c5990e03e03729e6de4d4c4edf3f39435020244989"}, + {file = "semgrep-0.82.0-cp37.cp38.cp39.py37.py38.py39-none-macosx_10_14_x86_64.whl", hash = "sha256:037124db822a0c9235ea6cfbc637f06771ca2882d181dfdbd460c430bf51d7ec"}, + {file = "semgrep-0.82.0.tar.gz", hash = "sha256:aa6c57d08602ffde3bf36159c0325d6d72f70dc634cd237f30ff46f7d6b78be3"}, +] +tqdm = [ + {file = "tqdm-4.62.3-py2.py3-none-any.whl", hash = "sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c"}, + {file = "tqdm-4.62.3.tar.gz", hash = "sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d"}, +] +typing-extensions = [ + {file = "typing_extensions-4.1.0-py3-none-any.whl", hash = "sha256:c13180fbaa7cd97065a4915ceba012bdb31dc34743e63ddee16360161d358414"}, + {file = "typing_extensions-4.1.0.tar.gz", hash = "sha256:ba97c5143e5bb067b57793c726dd857b1671d4b02ced273ca0538e71ff009095"}, +] +urllib3 = [ + {file = "urllib3-1.26.8-py2.py3-none-any.whl", hash = "sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed"}, + {file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"}, +] +wcmatch = [ + {file = "wcmatch-8.3-py3-none-any.whl", hash = "sha256:7141d2c85314253f16b38cb3d6cc0fb612918d407e1df3ccc2be7c86cc259c22"}, + {file = "wcmatch-8.3.tar.gz", hash = "sha256:371072912398af61d1e4e78609e18801c6faecd3cb36c54c82556a60abc965db"}, +] +zipp = [ + {file = "zipp-3.7.0-py3-none-any.whl", hash = "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375"}, + {file = "zipp-3.7.0.tar.gz", hash = "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d"}, +] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..b830e65 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,11 @@ +[tool.poetry] +name = "pushbits" +version = "0.0.0" +description = "" +authors = [] + +[tool.poetry.dependencies] +python = "^3.7" + +[tool.poetry.dev-dependencies] +semgrep = "^0.82.0" diff --git a/tests/semgrep/go/aws-lambda/security/database-sqli.yaml b/tests/semgrep/go/aws-lambda/security/database-sqli.yaml new file mode 100644 index 0000000..f4c3bba --- /dev/null +++ b/tests/semgrep/go/aws-lambda/security/database-sqli.yaml @@ -0,0 +1,51 @@ +rules: +- id: database-sqli + languages: + - go + message: >- + Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled + and not properly sanitized. In order to prevent SQL injection, + used parameterized queries or prepared statements instead. + You can use prepared statements with the 'Prepare' and 'PrepareContext' calls. + mode: taint + metadata: + references: + - 'https://pkg.go.dev/database/sql#DB.Query' + category: security + owasp: "A1: Injection" + cwe: "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')" + technology: + - aws-lambda + - database + - sql + pattern-sinks: + - patterns: + - pattern: $QUERY + - pattern-either: + - pattern: $DB.Exec($QUERY,...) + - pattern: $DB.ExecContent($QUERY,...) + - pattern: $DB.Query($QUERY,...) + - pattern: $DB.QueryContext($QUERY,...) + - pattern: $DB.QueryRow($QUERY,...) + - pattern: $DB.QueryRowContext($QUERY,...) + - pattern-inside: | + import "database/sql" + ... + pattern-sources: + - patterns: + - pattern-either: + - pattern-inside: | + func $HANDLER($CTX $CTXTYPE, $EVENT $TYPE, ...) {...} + ... + lambda.Start($HANDLER, ...) + - patterns: + - pattern-inside: | + func $HANDLER($EVENT $TYPE) {...} + ... + lambda.Start($HANDLER, ...) + - pattern-not-inside: | + func $HANDLER($EVENT context.Context) {...} + ... + lambda.Start($HANDLER, ...) + - pattern: $EVENT + severity: WARNING diff --git a/tests/semgrep/go/gorilla/security/audit/handler-assignment-from-multiple-sources.yaml b/tests/semgrep/go/gorilla/security/audit/handler-assignment-from-multiple-sources.yaml new file mode 100644 index 0000000..6663481 --- /dev/null +++ b/tests/semgrep/go/gorilla/security/audit/handler-assignment-from-multiple-sources.yaml @@ -0,0 +1,57 @@ +rules: + - id: handler-assignment-from-multiple-sources + metadata: + cwe: "CWE-289: Authentication Bypass by Alternate Name" + owasp: "A2: Broken Authentication" + owaspapi: "API1: Broken Object Level Authorization" + category: security + technology: + - gorilla + confidence: MEDIUM + patterns: + - pattern-inside: | + func $HANDLER(..., $R *http.Request, ...) { + ... + } + - pattern-not: | + $VAR = true + ... + $VAR = false + - pattern-not: | + $VAR = false + ... + $VAR = true + - pattern-not: | + $VAR = $X + ... + $VAR = $X + - pattern-not: | + $VAR = $X + ... + $VAR = $Z(..., $VAR, ...) + - pattern-not: | + $VAR = $X + ... + $VAR = $Z($W(..., $VAR, ...)) + - pattern-not: | + $VAR = $X + ... + $VAR = $VAR[:$Z(..., $VAR, ...)] + - pattern-not: | + $VAR = $X + ... + $VAR = $VAR[$Z(..., $VAR, ...):] + - pattern-not: | + $VAR = $X + ... + $VAR = $VAR[$Z(..., $VAR, ...)] + - pattern: | + $VAR = $X + ... + $VAR = $Y + message: + "Variable $VAR is assigned from two different sources: '$X' and '$Y'. Make\ + \ sure this is intended, as this could cause logic bugs if they are treated as\ + \ they are the same object." + languages: [go] + severity: WARNING diff --git a/tests/semgrep/go/gorilla/security/audit/session-cookie-missing-httponly.yaml b/tests/semgrep/go/gorilla/security/audit/session-cookie-missing-httponly.yaml new file mode 100644 index 0000000..1f64f96 --- /dev/null +++ b/tests/semgrep/go/gorilla/security/audit/session-cookie-missing-httponly.yaml @@ -0,0 +1,33 @@ +rules: + - id: session-cookie-missing-httponly + patterns: + - pattern-not-inside: | + &sessions.Options{ + ..., + HttpOnly: true, + ..., + } + - pattern: | + &sessions.Options{ + ..., + } + message: >- + A session cookie was detected without setting the 'HttpOnly' flag. + The 'HttpOnly' flag for cookies instructs the browser to forbid + client-side scripts from reading the cookie which mitigates XSS + attacks. Set the 'HttpOnly' flag by setting 'HttpOnly' to 'true' + in the Options struct. + metadata: + cwe: "CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag" + owasp: "A3: Sensitive Data Exposure" + references: + - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/user/session/session.go#L69 + category: security + technology: + - gorilla + confidence: MEDIUM + fix-regex: + regex: (HttpOnly\s*:\s+)false + replacement: \1true + severity: WARNING + languages: [go] diff --git a/tests/semgrep/go/gorilla/security/audit/session-cookie-missing-secure.yaml b/tests/semgrep/go/gorilla/security/audit/session-cookie-missing-secure.yaml new file mode 100644 index 0000000..f22f5d8 --- /dev/null +++ b/tests/semgrep/go/gorilla/security/audit/session-cookie-missing-secure.yaml @@ -0,0 +1,32 @@ +rules: + - id: session-cookie-missing-secure + patterns: + - pattern-not-inside: | + &sessions.Options{ + ..., + Secure: true, + ..., + } + - pattern: | + &sessions.Options{ + ..., + } + message: >- + A session cookie was detected without setting the 'Secure' flag. + The 'secure' flag for cookies prevents the client from transmitting + the cookie over insecure channels such as HTTP. Set the 'Secure' + flag by setting 'Secure' to 'true' in the Options struct. + metadata: + cwe: "CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute" + owasp: "A3: Sensitive Data Exposure" + references: + - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/user/session/session.go#L69 + category: security + technology: + - gorilla + confidence: MEDIUM + fix-regex: + regex: (Secure\s*:\s+)false + replacement: \1true + severity: WARNING + languages: [go] diff --git a/tests/semgrep/go/grpc/security/grpc-client-insecure-connection.yaml b/tests/semgrep/go/grpc/security/grpc-client-insecure-connection.yaml new file mode 100644 index 0000000..cc9b08f --- /dev/null +++ b/tests/semgrep/go/grpc/security/grpc-client-insecure-connection.yaml @@ -0,0 +1,26 @@ +rules: + - id: grpc-client-insecure-connection + metadata: + cwe: "CWE-300: Channel Accessible by Non-Endpoint" + references: + - https://blog.gopheracademy.com/advent-2019/go-grps-and-tls/#connection-without-encryption + category: security + technology: + - grpc + confidence: HIGH + message: >- + Found an insecure gRPC connection using 'grpc.WithInsecure()'. This creates a + connection without encryption to a gRPC + server. A malicious attacker could tamper with the gRPC message, which could compromise + the machine. Instead, establish + a secure connection with an + SSL certificate using the 'grpc.WithTransportCredentials()' function. You can + create a create credentials using a 'tls.Config{}' + struct with 'credentials.NewTLS()'. The final fix looks like this: 'grpc.WithTransportCredentials(credentials.NewTLS())'. + languages: + - go + severity: ERROR + pattern: $GRPC.Dial($ADDR, ..., $GRPC.WithInsecure(...), ...) + fix-regex: + regex: (.*)WithInsecure\(.*?\) + replacement: \1WithTransportCredentials(credentials.NewTLS()) diff --git a/tests/semgrep/go/grpc/security/grpc-server-insecure-connection.yaml b/tests/semgrep/go/grpc/security/grpc-server-insecure-connection.yaml new file mode 100644 index 0000000..3168df9 --- /dev/null +++ b/tests/semgrep/go/grpc/security/grpc-server-insecure-connection.yaml @@ -0,0 +1,41 @@ +rules: + - id: grpc-server-insecure-connection + metadata: + cwe: "CWE-300: Channel Accessible by Non-Endpoint" + references: + - https://blog.gopheracademy.com/advent-2019/go-grps-and-tls/#connection-without-encryption + category: security + technology: + - grpc + confidence: HIGH + message: >- + Found an insecure gRPC server without 'grpc.Creds()' or options with credentials. + This allows for a connection without + encryption to this server. + A malicious attacker could tamper with the gRPC message, which could compromise + the machine. Include credentials derived + from an SSL certificate in order to create a secure gRPC connection. You can create + credentials using 'credentials.NewServerTLSFromFile("cert.pem", + "cert.key")'. + languages: + - go + severity: ERROR + patterns: + - pattern-not: grpc.NewServer(..., grpc.Creds(...), ...) + - pattern-not-inside: | + $OPTS := []grpc.ServerOption{ + ..., + grpc.Creds(credentials.NewClientTLSFromCert(...)), + ..., + } + grpc.NewServer($OPTS...) + - pattern-not-inside: | + $CREDS := credentials.NewClientTLSFromCert(...) + ... + $OPTS := []grpc.ServerOption{ + ..., + $CREDS, + ..., + } + grpc.NewServer($OPTS...) + - pattern: grpc.NewServer(...) diff --git a/tests/semgrep/go/jwt-go/security/audit/jwt-parse-unverified.yaml b/tests/semgrep/go/jwt-go/security/audit/jwt-parse-unverified.yaml new file mode 100644 index 0000000..103575c --- /dev/null +++ b/tests/semgrep/go/jwt-go/security/audit/jwt-parse-unverified.yaml @@ -0,0 +1,22 @@ +rules: + - id: jwt-go-parse-unverified + message: >- + Detected the decoding of a JWT token without a verify step. + Don't use `ParseUnverified` unless you know what you're doing + This method parses the token but doesn't validate the signature. It's only ever useful in cases where you know the signature is valid (because it has been checked previously in the stack) and you want to extract values from it. + metadata: + cwe: "CWE-345: Insufficient Verification of Data Authenticity" + owasp: "A2: Broken Authentication" + source-rule-url: https://r2c.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + category: security + technology: + - jwt + confidence: MEDIUM + languages: [go] + severity: WARNING + patterns: + - pattern-inside: | + import "github.com/dgrijalva/jwt-go" + ... + - pattern: | + $JWT.ParseUnverified(...) diff --git a/tests/semgrep/go/jwt-go/security/jwt-none-alg.yaml b/tests/semgrep/go/jwt-go/security/jwt-none-alg.yaml new file mode 100644 index 0000000..2c83506 --- /dev/null +++ b/tests/semgrep/go/jwt-go/security/jwt-none-alg.yaml @@ -0,0 +1,26 @@ +rules: + - id: jwt-go-none-algorithm + message: >- + Detected use of the 'none' algorithm in a JWT token. + The 'none' algorithm assumes the integrity of the token has already + been verified. This would allow a malicious actor to forge a JWT token + that will automatically be verified. Do not explicitly use the 'none' + algorithm. Instead, use an algorithm such as 'HS256'. + metadata: + cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" + owasp: "A2: Broken Authentication" + source-rule-url: https://r2c.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ + category: security + technology: + - jwt + confidence: HIGH + languages: [go] + severity: ERROR + patterns: + - pattern-inside: | + import "github.com/dgrijalva/jwt-go" + ... + - pattern-either: + - pattern: | + jwt.SigningMethodNone + - pattern: jwt.UnsafeAllowNoneSignatureType diff --git a/tests/semgrep/go/jwt-go/security/jwt.yaml b/tests/semgrep/go/jwt-go/security/jwt.yaml new file mode 100644 index 0000000..de76549 --- /dev/null +++ b/tests/semgrep/go/jwt-go/security/jwt.yaml @@ -0,0 +1,19 @@ +rules: + - id: hardcoded-jwt-key + metadata: + cwe: "CWE-798: Use of Hard-coded Credentials" + owasp: "A2: Broken Authentication" + category: security + technology: + - jwt + confidence: MEDIUM + pattern-either: + - pattern: | + $X = []byte("...") + ... + $Y := $TOKEN.SignedString($X) + - pattern: | + $TOKEN.SignedString([]byte("...")) + message: JWT token is hardcoded + languages: [go] + severity: WARNING diff --git a/tests/semgrep/go/lang/best-practice/channel-guarded-with-mutex.yaml b/tests/semgrep/go/lang/best-practice/channel-guarded-with-mutex.yaml new file mode 100644 index 0000000..ab61095 --- /dev/null +++ b/tests/semgrep/go/lang/best-practice/channel-guarded-with-mutex.yaml @@ -0,0 +1,22 @@ +rules: + - id: channel-guarded-with-mutex + pattern-either: + - pattern: | + $MUX.Lock() + $VALUE <- $CHANNEL + $MUX.Unlock() + - pattern: | + $MUX.Lock() + $VALUE = <- $CHANNEL + $MUX.Unlock() + message: >- + Detected a channel guarded with a mutex. Channels already have + an internal mutex, so this is unnecessary. Remove the mutex. + See https://hackmongo.com/page/golang-antipatterns/#guarded-channel + for more information. + languages: [go] + severity: WARNING + metadata: + category: best-practice + technology: + - go diff --git a/tests/semgrep/go/lang/best-practice/hidden-goroutine.yaml b/tests/semgrep/go/lang/best-practice/hidden-goroutine.yaml new file mode 100644 index 0000000..16425cc --- /dev/null +++ b/tests/semgrep/go/lang/best-practice/hidden-goroutine.yaml @@ -0,0 +1,27 @@ +rules: + - id: hidden-goroutine + patterns: + - pattern-not: | + func $FUNC(...) { + go func() { + ... + }(...) + $MORE + } + - pattern: | + func $FUNC(...) { + go func() { + ... + }(...) + } + message: >- + Detected a hidden goroutine. Function invocations are expected to synchronous, + and this function will execute asynchronously because all it does is call a + goroutine. Instead, remove the internal goroutine and call the function using + 'go'. + languages: [go] + severity: WARNING + metadata: + category: best-practice + technology: + - go diff --git a/tests/semgrep/go/lang/correctness/looppointer.yaml b/tests/semgrep/go/lang/correctness/looppointer.yaml new file mode 100644 index 0000000..43f8113 --- /dev/null +++ b/tests/semgrep/go/lang/correctness/looppointer.yaml @@ -0,0 +1,29 @@ +rules: + - id: exported_loop_pointer + message: >- + `$VALUE` is a loop pointer that may be exported from the loop. This pointer is + shared between loop iterations, so the exported reference will always point to + the last loop value, which is likely unintentional. To fix, copy the pointer to + a new pointer within the loop. + metadata: + references: + - https://github.com/kyoh86/looppointer + category: correctness + technology: + - go + severity: WARNING + languages: + - go + pattern-either: + - pattern: | + for _, $VALUE := range $SOURCE { + <... &($VALUE) ...> + } + - pattern: | + for _, $VALUE := range $SOURCE { + <... func() { <... &$VALUE ...> } ...> + } + - pattern: | + for _, $VALUE := range $SOURCE { + <... $ANYTHING(..., <... $VALUE ...>, ...) ...> + } diff --git a/tests/semgrep/go/lang/correctness/overflow/overflow.yaml b/tests/semgrep/go/lang/correctness/overflow/overflow.yaml new file mode 100644 index 0000000..09c753f --- /dev/null +++ b/tests/semgrep/go/lang/correctness/overflow/overflow.yaml @@ -0,0 +1,39 @@ +rules: + - id: integer-overflow-int16 + message: + Detected conversion of the result of a strconv.Atoi command to an int16. This could lead to an integer overflow, + which could possibly result in unexpected behavior and even privilege escalation. Instead, use `strconv.ParseInt`. + languages: [go] + severity: WARNING + patterns: + - pattern: | + $F, $ERR := strconv.Atoi($NUM) + ... + int16($F) + - metavariable-comparison: + metavariable: $NUM + comparison: $NUM > 32767 or $NUM < -32768 + strip: true + metadata: + category: correctness + technology: + - go + - id: integer-overflow-int32 + message: + Detected conversion of the result of a strconv.Atoi command to an int32. This could lead to an integer overflow, + which could possibly result in unexpected behavior and even privilege escalation. Instead, use `strconv.ParseInt`. + languages: [go] + severity: WARNING + patterns: + - pattern: | + $F, $ERR := strconv.Atoi($NUM) + ... + int32($F) + - metavariable-comparison: + metavariable: $NUM + comparison: $NUM > 2147483647 or $NUM < -2147483648 + strip: true + metadata: + category: correctness + technology: + - go diff --git a/tests/semgrep/go/lang/correctness/permissions/file_permission.yaml b/tests/semgrep/go/lang/correctness/permissions/file_permission.yaml new file mode 100644 index 0000000..9a316ea --- /dev/null +++ b/tests/semgrep/go/lang/correctness/permissions/file_permission.yaml @@ -0,0 +1,25 @@ +rules: + - id: incorrect-default-permission + message: + Detected file permissions that are set to more than `0600` (user/owner can read and write). Setting file permissions + to higher than `0600` is most likely unnecessary and violates the principle of least privilege. Instead, set permissions + to be `0600` or less for os.Chmod, os.Mkdir, os.OpenFile, os.MkdirAll, and ioutil.WriteFile + metadata: + cwe: "CWE-276: Incorrect Default Permissions" + source_rule_url: https://github.com/securego/gosec + category: correctness + technology: + - go + severity: WARNING + languages: [go] + patterns: + - pattern-either: + - pattern: os.Chmod($NAME, $PERM) + - pattern: os.Mkdir($NAME, $PERM) + - pattern: os.OpenFile($NAME, $FLAG, $PERM) + - pattern: os.MkdirAll($NAME, $PERM) + - pattern: ioutil.WriteFile($NAME, $DATA, $PERM) + - metavariable-comparison: + metavariable: $PERM + comparison: $PERM > 0o600 + base: 8 diff --git a/tests/semgrep/go/lang/correctness/use-filepath-join.yaml b/tests/semgrep/go/lang/correctness/use-filepath-join.yaml new file mode 100644 index 0000000..2c6b1ad --- /dev/null +++ b/tests/semgrep/go/lang/correctness/use-filepath-join.yaml @@ -0,0 +1,16 @@ +rules: +- id: use-filepath-join + languages: [go] + severity: WARNING + message: >- + `path.Join(...)` always joins using a forward slash. This may cause + issues on Windows or other systems using a different delimiter. Use + `filepath.Join(...)` instead which uses OS-specific path separators. + pattern: path.Join(...) + metadata: + category: correctness + references: + - https://parsiya.net/blog/2019-03-09-path.join-considered-harmful/ + - https://go.dev/src/path/path.go?s=4034:4066#L145 + technology: + - go diff --git a/tests/semgrep/go/lang/correctness/useless-eqeq.yaml b/tests/semgrep/go/lang/correctness/useless-eqeq.yaml new file mode 100644 index 0000000..5febc58 --- /dev/null +++ b/tests/semgrep/go/lang/correctness/useless-eqeq.yaml @@ -0,0 +1,31 @@ +rules: + - id: eqeq-is-bad + patterns: + - pattern-not-inside: assert(...) + - pattern-either: + - pattern: $X == $X + - pattern: $X != $X + - pattern-not: 1 == 1 + message: + Detected useless comparison operation `$X == $X` or `$X != $X`. This will always return 'True' or 'False' and therefore + is not necessary. Instead, remove this comparison operation or use another comparison expression that is not deterministic. + languages: [go] + severity: ERROR + metadata: + category: correctness + technology: + - go + - id: hardcoded-eq-true-or-false + message: + Detected useless if statement. 'if (True)' and 'if (False)' always result in the same behavior, and therefore is + not necessary in the code. Remove the 'if (False)' expression completely or just the 'if (True)' comparison depending + on which expression is in the code. + languages: [go] + severity: ERROR + pattern-either: + - pattern: if (true) { ... } + - pattern: if (false) { ... } + metadata: + category: correctness + technology: + - go diff --git a/tests/semgrep/go/lang/maintainability/useless-ifelse.yaml b/tests/semgrep/go/lang/maintainability/useless-ifelse.yaml new file mode 100644 index 0000000..f5b9b4b --- /dev/null +++ b/tests/semgrep/go/lang/maintainability/useless-ifelse.yaml @@ -0,0 +1,33 @@ +rules: + - id: useless-if-conditional + message: + Detected an if block that checks for the same condition on both branches (`$X`). The second condition check is + useless as it is the same as the first, and therefore can be removed from the code, + languages: [go] + severity: WARNING + pattern: | + if ($X) { + ... + } else if ($X) { + ... + } + metadata: + category: maintainability + technology: + - go + - id: useless-if-body + pattern: | + if ($X) { + $S + } else { + $S + } + message: + Detected identical statements in the if body and the else body of an if-statement. This will lead to the same code + being executed no matter what the if-expression evaluates to. Instead, remove the if statement. + languages: [go] + severity: WARNING + metadata: + category: maintainability + technology: + - go diff --git a/tests/semgrep/go/lang/security/audit/crypto/bad_imports.yaml b/tests/semgrep/go/lang/security/audit/crypto/bad_imports.yaml new file mode 100644 index 0000000..2d9870b --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/crypto/bad_imports.yaml @@ -0,0 +1,48 @@ +rules: + - id: insecure-module-used + message: >- + Detected use of an insecure cryptographic hashing method. This method is known + to be broken and easily compromised. Use SHA256 or SHA3 instead. + metadata: + owasp: "A9: Using Components with Known Vulnerabilities" + cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" + source-rule-url: https://github.com/securego/gosec + references: + - https://godoc.org/golang.org/x/crypto/sha3 + category: security + technology: + - go + confidence: MEDIUM + languages: [go] + severity: WARNING + pattern-either: + - patterns: + - pattern-inside: | + import "crypto/md5" + ... + - pattern: | + md5.$FUNC(...) + - patterns: + - pattern-inside: | + import "crypto/des" + ... + - pattern: | + des.$FUNC(...) + - patterns: + - pattern-inside: | + import "crypto/sha1" + ... + - pattern: | + sha1.$FUNC(...) + - patterns: + - pattern-inside: | + import "crypto/rc4" + ... + - pattern: | + rc4.$FUNC(...) + - patterns: + - pattern-inside: | + import "net/http/cgi" + ... + - pattern: | + cgi.$FUNC(...) diff --git a/tests/semgrep/go/lang/security/audit/crypto/insecure_ssh.yaml b/tests/semgrep/go/lang/security/audit/crypto/insecure_ssh.yaml new file mode 100644 index 0000000..dc706e6 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/crypto/insecure_ssh.yaml @@ -0,0 +1,23 @@ +rules: + - id: avoid-ssh-insecure-ignore-host-key + message: >- + Disabled host key verification detected. This allows man-in-the-middle + attacks. Use the 'golang.org/x/crypto/ssh/knownhosts' package to do + host key verification. + See https://skarlso.github.io/2019/02/17/go-ssh-with-host-key-verification/ + to learn more about the problem and how to fix it. + metadata: + cwe: "CWE-322: Key Exchange without Entity Authentication" + owasp: "A3: Sensitive Data Exposure" + source-rule-url: https://github.com/securego/gosec + references: + - https://skarlso.github.io/2019/02/17/go-ssh-with-host-key-verification/ + - https://gist.github.com/Skarlso/34321a230cf0245018288686c9e70b2d + category: security + technology: + - go + confidence: MEDIUM + languages: [go] + severity: WARNING + pattern: |- + ssh.InsecureIgnoreHostKey() diff --git a/tests/semgrep/go/lang/security/audit/crypto/math_random.yaml b/tests/semgrep/go/lang/security/audit/crypto/math_random.yaml new file mode 100644 index 0000000..3ca932d --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/crypto/math_random.yaml @@ -0,0 +1,32 @@ +rules: + - id: math-random-used + metadata: + cwe: "CWE-338: Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)" + owasp: "A3: Sensitive Data Exposure" + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#secure-random-number-generation + category: security + technology: + - go + confidence: MEDIUM + message: Do not use `math/rand`. Use `crypto/rand` instead. + languages: [go] + severity: WARNING + pattern-either: + - patterns: + - pattern-inside: | + import mrand "math/rand" + ... + - pattern-either: + - pattern: mrand.Int() + - pattern: mrand.Read(...) + - patterns: + - pattern-inside: | + import "math/rand" + ... + - pattern-not-inside: | + import "crypto/rand" + ... + - pattern-either: + - pattern: rand.Int() + - pattern: rand.Read(...) diff --git a/tests/semgrep/go/lang/security/audit/crypto/missing-ssl-minversion.yaml b/tests/semgrep/go/lang/security/audit/crypto/missing-ssl-minversion.yaml new file mode 100644 index 0000000..15ab7e0 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/crypto/missing-ssl-minversion.yaml @@ -0,0 +1,28 @@ +rules: + - id: missing-ssl-minversion + message: >- + `MinVersion` is missing from this TLS configuration. The default + value is TLS1.0 which is considered insecure. Explicitly set the + `MinVersion` to a secure version of TLS, such as `VersionTLS13`. + metadata: + cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" + owasp: "A9: Using Components with Known Vulnerabilities" + source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls_config.go + references: + - https://golang.org/doc/go1.14#crypto/tls + - https://golang.org/pkg/crypto/tls/#:~:text=MinVersion + - https://www.us-cert.gov/ncas/alerts/TA14-290A + category: security + technology: + - go + confidence: HIGH + languages: [go] + severity: WARNING + patterns: + - pattern: |- + tls.Config{...} + - pattern-not-inside: |- + tls.Config{..., MinVersion: ..., ...} + fix-regex: + regex: Config\s*\{ + replacement: "Config{MinVersion: SSL.VersionTLS13," diff --git a/tests/semgrep/go/lang/security/audit/crypto/ssl.yaml b/tests/semgrep/go/lang/security/audit/crypto/ssl.yaml new file mode 100644 index 0000000..d01a478 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/crypto/ssl.yaml @@ -0,0 +1,23 @@ +rules: + - id: ssl-v3-is-insecure + message: >- + SSLv3 is insecure because it has known vulnerabilities. + Starting with go1.14, SSLv3 will be removed. Instead, use + 'tls.VersionTLS13'. + metadata: + cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" + owasp: "A9: Using Components with Known Vulnerabilities" + source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls_config.go + references: + - https://golang.org/doc/go1.14#crypto/tls + - https://www.us-cert.gov/ncas/alerts/TA14-290A + category: security + technology: + - go + confidence: HIGH + languages: [go] + severity: WARNING + fix-regex: + regex: VersionSSL30 + replacement: VersionTLS13 + pattern: "tls.Config{..., MinVersion: $TLS.VersionSSL30, ...}" diff --git a/tests/semgrep/go/lang/security/audit/crypto/tls.yaml b/tests/semgrep/go/lang/security/audit/crypto/tls.yaml new file mode 100644 index 0000000..7f19872 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/crypto/tls.yaml @@ -0,0 +1,45 @@ +rules: + - id: tls-with-insecure-cipher + message: >- + Detected an insecure CipherSuite via the 'tls' module. This suite is considered + weak. + Use the function 'tls.CipherSuites()' to get a list of good cipher suites. + See https://golang.org/pkg/crypto/tls/#InsecureCipherSuites + for why and what other cipher suites to use. + metadata: + cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" + owasp: "A9: Using Components with Known Vulnerabilities" + source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls.go + references: + - https://golang.org/pkg/crypto/tls/#InsecureCipherSuites + category: security + technology: + - go + confidence: HIGH + languages: [go] + severity: WARNING + pattern-either: + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_RC4_128_SHA,...}} + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_AES_128_CBC_SHA256,...}} + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,...}} + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,...}} + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,...}} + - pattern: | + tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,...}} + - pattern: | + tls.CipherSuite{..., TLS_RSA_WITH_RC4_128_SHA ,...} + - pattern: | + tls.CipherSuite{..., TLS_RSA_WITH_AES_128_CBC_SHA256 ,...} + - pattern: | + tls.CipherSuite{..., TLS_ECDHE_ECDSA_WITH_RC4_128_SHA ,...} + - pattern: | + tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_RC4_128_SHA ,...} + - pattern: | + tls.CipherSuite{..., TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 ,...} + - pattern: |- + tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 ,...} diff --git a/tests/semgrep/go/lang/security/audit/crypto/use_of_weak_crypto.yaml b/tests/semgrep/go/lang/security/audit/crypto/use_of_weak_crypto.yaml new file mode 100644 index 0000000..1d80f52 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/crypto/use_of_weak_crypto.yaml @@ -0,0 +1,73 @@ +rules: + - id: use-of-md5 + message: >- + Detected MD5 hash algorithm which is considered insecure. MD5 is not + collision resistant and is therefore not suitable as a cryptographic + signature. Use SHA256 or SHA3 instead. + languages: [go] + severity: WARNING + metadata: + owasp: "A9: Using Components with Known Vulnerabilities" + cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" + source-rule-url: https://github.com/securego/gosec#available-rules + category: security + technology: + - go + confidence: MEDIUM + pattern-either: + - pattern: | + md5.New() + - pattern: | + md5.Sum(...) + - id: use-of-sha1 + message: >- + Detected SHA1 hash algorithm which is considered insecure. SHA1 is not + collision resistant and is therefore not suitable as a cryptographic + signature. Use SHA256 or SHA3 instead. + languages: [go] + severity: WARNING + metadata: + owasp: "A9: Using Components with Known Vulnerabilities" + cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" + source-rule-url: https://github.com/securego/gosec#available-rules + category: security + technology: + - go + pattern-either: + - pattern: | + sha1.New() + - pattern: | + sha1.Sum(...) + - id: use-of-DES + message: >- + Detected DES cipher algorithm which is insecure. The algorithm is + considered weak and has been deprecated. Use AES instead. + languages: [go] + severity: WARNING + metadata: + owasp: "A9: Using Components with Known Vulnerabilities" + cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" + source-rule-url: https://github.com/securego/gosec#available-rules + category: security + technology: + - go + pattern-either: + - pattern: | + des.NewTripleDESCipher(...) + - pattern: | + des.NewCipher(...) + - id: use-of-rc4 + message: >- + Detected RC4 cipher algorithm which is insecure. The algorithm has many + known vulnerabilities. Use AES instead. + languages: [go] + severity: WARNING + metadata: + owasp: "A9: Using Components with Known Vulnerabilities" + cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" + source-rule-url: https://github.com/securego/gosec#available-rules + category: security + technology: + - go + pattern: |- + rc4.NewCipher(...) diff --git a/tests/semgrep/go/lang/security/audit/crypto/use_of_weak_rsa_key.yaml b/tests/semgrep/go/lang/security/audit/crypto/use_of_weak_rsa_key.yaml new file mode 100644 index 0000000..ac6e0bb --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/crypto/use_of_weak_rsa_key.yaml @@ -0,0 +1,24 @@ +rules: + - id: use-of-weak-rsa-key + message: RSA keys should be at least 2048 bits + languages: [go] + severity: WARNING + metadata: + cwe: "CWE-326: Inadequate Encryption Strength" + owasp: "A3: Sensitive Data Exposure" + source-rule-url: https://github.com/securego/gosec/blob/master/rules/rsa.go + references: + - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms + category: security + technology: + - go + confidence: MEDIUM + patterns: + - pattern-either: + - pattern: | + rsa.GenerateKey(..., $BITS) + - pattern: | + rsa.GenerateMultiPrimeKey(..., $BITS) + - metavariable-comparison: + metavariable: $BITS + comparison: $BITS < 2048 diff --git a/tests/semgrep/go/lang/security/audit/dangerous-command-write.yaml b/tests/semgrep/go/lang/security/audit/dangerous-command-write.yaml new file mode 100644 index 0000000..872e7f6 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/dangerous-command-write.yaml @@ -0,0 +1,35 @@ +rules: + - id: dangerous-command-write + patterns: + - pattern: | + $CW.Write($BYTE) + - pattern-inside: | + $CW,$ERR := $CMD.StdinPipe() + ... + - pattern-not: | + $CW.Write("...") + - pattern-not: | + $CW.Write([]byte("...")) + - pattern-not: | + $CW.Write([]byte("..."+"...")) + - pattern-not-inside: | + $BYTE = []byte("..."); + ... + - pattern-not-inside: | + $BYTE = []byte("..."+"..."); + ... + - pattern-inside: | + import "os/exec" + ... + message: >- + Detected non-static command inside Write. Audit the input to '$CW.Write'. + If unverified user data can reach this call site, this is a code injection + vulnerability. A malicious actor can inject a malicious script to execute + arbitrary code. + severity: ERROR + languages: [go] + metadata: + category: security + technology: + - go + confidence: MEDIUM diff --git a/tests/semgrep/go/lang/security/audit/dangerous-exec-cmd.yaml b/tests/semgrep/go/lang/security/audit/dangerous-exec-cmd.yaml new file mode 100644 index 0000000..18d190c --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/dangerous-exec-cmd.yaml @@ -0,0 +1,76 @@ +rules: + - id: dangerous-exec-cmd + patterns: + - pattern-either: + - patterns: + - pattern: | + exec.Cmd {...,Path: $CMD,...} + - pattern-not: | + exec.Cmd {...,Path: "...",...} + - pattern-not-inside: | + $CMD,$ERR := exec.LookPath("..."); + ... + - pattern-not-inside: | + $CMD = "..."; + ... + - patterns: + - pattern: | + exec.Cmd {...,Args: $ARGS,...} + - pattern-not: | + exec.Cmd {...,Args: []string{...},...} + - pattern-not-inside: | + $ARGS = []string{"...",...}; + ... + - pattern-not-inside: | + $CMD = "..."; + ... + $ARGS = []string{$CMD,...}; + ... + - pattern-not-inside: | + $CMD = exec.LookPath("..."); + ... + $ARGS = []string{$CMD,...}; + ... + - patterns: + - pattern: | + exec.Cmd {...,Args: []string{$CMD,...},...} + - pattern-not: | + exec.Cmd {...,Args: []string{"...",...},...} + - pattern-not-inside: | + $CMD,$ERR := exec.LookPath("..."); + ... + - pattern-not-inside: | + $CMD = "..."; + ... + - patterns: + - pattern-either: + - pattern: | + exec.Cmd {...,Args: []string{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$EXE,...},...} + - patterns: + - pattern: | + exec.Cmd {...,Args: []string{$CMD,"-c",$EXE,...},...} + - pattern-inside: | + $CMD,$ERR := exec.LookPath("=~/(sh|bash|ksh|csh|tcsh|zsh)/"); + ... + - pattern-not: | + exec.Cmd {...,Args: []string{"...","...","...",...},...} + - pattern-not-inside: | + $EXE = "..."; + ... + - pattern-inside: | + import "os/exec" + ... + message: >- + Detected non-static command inside exec.Cmd. Audit the input to 'exec.Cmd'. + If unverified user data can reach this call site, this is a code injection + vulnerability. A malicious actor can inject a malicious script to execute + arbitrary code. + metadata: + cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')" + owasp: "A1: Injection" + category: security + technology: + - go + confidence: MEDIUM + severity: ERROR + languages: [go] diff --git a/tests/semgrep/go/lang/security/audit/dangerous-exec-command.yaml b/tests/semgrep/go/lang/security/audit/dangerous-exec-command.yaml new file mode 100644 index 0000000..d445e03 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/dangerous-exec-command.yaml @@ -0,0 +1,47 @@ +rules: + - id: dangerous-exec-command + patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: | + exec.Command($CMD,...) + - pattern: | + exec.CommandContext($CTX,$CMD,...) + - pattern-not: | + exec.Command("...",...) + - pattern-not: | + exec.CommandContext($CTX,"...",...) + - patterns: + - pattern-either: + - pattern: | + exec.Command("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$CMD,...) + - pattern: | + exec.CommandContext($CTX,"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$CMD,...) + - pattern-not: | + exec.Command("...","...","...",...) + - pattern-not: | + exec.CommandContext($CTX,"...","...","...",...) + - pattern-inside: | + import "os/exec" + ... + - pattern-not-inside: | + $CMD,$ERR := exec.LookPath("..."); + ... + - pattern-not-inside: | + $CMD = "..."; + ... + message: >- + Detected non-static command inside Command. Audit the input to 'exec.Command'. + If unverified user data can reach this call site, this is a code injection + vulnerability. A malicious actor can inject a malicious script to execute + arbitrary code. + metadata: + cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')" + owasp: "A1: Injection" + category: security + technology: + - go + confidence: MEDIUM + severity: ERROR + languages: [go] diff --git a/tests/semgrep/go/lang/security/audit/dangerous-syscall-exec.yaml b/tests/semgrep/go/lang/security/audit/dangerous-syscall-exec.yaml new file mode 100644 index 0000000..df96093 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/dangerous-syscall-exec.yaml @@ -0,0 +1,88 @@ +rules: + - id: dangerous-syscall-exec + patterns: + - pattern-either: + - patterns: + - pattern: | + syscall.$METHOD($BIN,...) + - pattern-not: | + syscall.$METHOD("...",...) + - pattern-not-inside: | + $BIN,$ERR := exec.LookPath("..."); + ... + - pattern-not-inside: | + $BIN = "..."; + ... + - patterns: + - pattern: | + syscall.$METHOD($BIN,$ARGS,...) + - pattern-not: | + syscall.$METHOD($BIN,[]string{"...",...},...) + - pattern-not-inside: | + $ARGS := []string{"...",...}; + ... + - pattern-not-inside: | + $CMD = "..."; + ... + $ARGS = []string{$CMD,...}; + ... + - pattern-not-inside: | + $CMD,$ERR := exec.LookPath("..."); + ... + $ARGS = []string{$CMD,...}; + ... + - patterns: + - pattern: | + syscall.$METHOD($BIN,[]string{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$EXE,...},...) + - pattern-not: | + syscall.$METHOD($BIN,[]string{"...","...","...",...},...) + - patterns: + - pattern: | + syscall.$METHOD($BIN,$ARGS,...) + - pattern-either: + - pattern-inside: | + $ARGS := []string{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$EXE,...}; + ... + - pattern-inside: | + $CMD = "=~/(sh|bash|ksh|csh|tcsh|zsh)/"; + ... + $ARGS = []string{$CMD,"-c",$EXE,...}; + ... + - pattern-inside: | + $CMD,$ERR := exec.LookPath("=~/(sh|bash|ksh|csh|tcsh|zsh)/"); + ... + $ARGS = []string{$CMD,"-c",$EXE,...}; + ... + - pattern-not-inside: | + $ARGS := []string{"...","...","...",...}; + ... + - pattern-not-inside: | + $CMD = "..."; + ... + $ARGS = []string{$CMD,"...","...",...}; + ... + - pattern-not-inside: | + $CMD,$ERR := exec.LookPath("..."); + ... + $ARGS = []string{$CMD,"...","...",...}; + ... + - pattern-inside: | + import "syscall" + ... + - metavariable-regex: + metavariable: $METHOD + regex: (Exec|ForkExec) + message: >- + Detected non-static command inside Exec. Audit the input to 'syscall.Exec'. + If unverified user data can reach this call site, this is a code injection + vulnerability. A malicious actor can inject a malicious script to execute + arbitrary code. + metadata: + cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')" + owasp: "A1: Injection" + category: security + technology: + - go + confidence: MEDIUM + severity: ERROR + languages: [go] diff --git a/tests/semgrep/go/lang/security/audit/database/string-formatted-query.yaml b/tests/semgrep/go/lang/security/audit/database/string-formatted-query.yaml new file mode 100644 index 0000000..ca7960c --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/database/string-formatted-query.yaml @@ -0,0 +1,155 @@ +rules: + - id: string-formatted-query + languages: [go] + message: >- + String-formatted SQL query detected. This could lead to SQL injection if + the string is not sanitized properly. Audit this call to ensure the + SQL is not manipulable by external data. + severity: WARNING + metadata: + owasp: "A1: Injection" + cwe: "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')" + source-rule-url: https://github.com/securego/gosec + category: security + technology: + - go + confidence: MEDIUM + patterns: + - pattern-not-inside: | + $VAR = "..." + "..." + ... + $OBJ.$SINK(..., $VAR, ...) + - pattern-not: $OBJ.Exec("...") + - pattern-not: $OBJ.ExecContext($CTX, "...") + - pattern-not: $OBJ.Query("...") + - pattern-not: $OBJ.QueryContext($CTX, "...") + - pattern-not: $OBJ.QueryRow("...") + - pattern-not: $OBJ.QueryRow($CTX, "...") + - pattern-not: $OBJ.QueryRowContext($CTX, "...") + - pattern-either: + - pattern: $OBJ.Exec($X + ...) + - pattern: $OBJ.ExecContext($CTX, $X + ...) + - pattern: $OBJ.Query($X + ...) + - pattern: $OBJ.QueryContext($CTX, $X + ...) + - pattern: $OBJ.QueryRow($X + ...) + - pattern: $OBJ.QueryRow($CTX, $X + ...) + - pattern: $OBJ.QueryRowContext($CTX, $X + ...) + - pattern: $OBJ.Exec(fmt.$P("...", ...)) + - pattern: $OBJ.ExecContext($CTX, fmt.$P("...", ...)) + - pattern: $OBJ.Query(fmt.$P("...", ...)) + - pattern: $OBJ.QueryContext($CTX, fmt.$P("...", ...)) + - pattern: $OBJ.QueryRow(fmt.$P("...", ...)) + - pattern: $OBJ.QueryRow($CTX, fmt.$P("...", ...)) + - pattern: $OBJ.QueryRowContext($CTX, fmt.$P("...", ...)) + - pattern: | + $QUERY = "..." + ... + $QUERY = $FXN(..., $QUERY, ...) + ... + $OBJ.Exec($QUERY, ...) + - pattern: | + $QUERY = "..." + ... + $QUERY = $FXN(..., $QUERY, ...) + ... + $OBJ.Query($QUERY, ...) + - pattern: | + $QUERY = "..." + ... + $QUERY = $FXN(..., $QUERY, ...) + ... + $OBJ.ExecContext($CTX, $QUERY, ...) + - pattern: | + $QUERY = "..." + ... + $QUERY = $FXN(..., $QUERY, ...) + ... + $OBJ.QueryContext($CTX, $QUERY, ...) + - pattern: | + $QUERY = "..." + ... + $QUERY = $FXN(..., $QUERY, ...) + ... + $OBJ.QueryRow($QUERY) + - pattern: | + $QUERY = "..." + ... + $QUERY = $FXN(..., $QUERY, ...) + ... + $OBJ.QueryRow($CTX, $QUERY) + - pattern: | + $QUERY = "..." + ... + $QUERY = $FXN(..., $QUERY, ...) + ... + $OBJ.QueryRowContext($CTX, $QUERY, ...) + - pattern: | + $QUERY = "..." + ... + $OTHER = $FXN(..., $QUERY, ...) + ... + $OBJ.Exec($OTHER, ...) + - pattern: | + $QUERY = "..." + ... + $OTHER = $FXN(..., $QUERY, ...) + ... + $OBJ.Query($OTHER, ...) + - pattern: | + $QUERY = "..." + ... + $OTHER = $FXN(..., $QUERY, ...) + ... + $OBJ.ExecContext($CTX, $OTHER, ...) + - pattern: | + $QUERY = "..." + ... + $OTHER = $FXN(..., $QUERY, ...) + ... + $OBJ.QueryContext($CTX, $OTHER, ...) + - pattern: | + $QUERY = "..." + ... + $OTHER = $FXN(..., $QUERY, ...) + ... + $OBJ.QueryRow($OTHER) + - pattern: | + $QUERY = "..." + ... + $OTHER = $FXN(..., $QUERY, ...) + ... + $OBJ.QueryRow($CTX, $OTHER) + - pattern: | + $QUERY = "..." + ... + $OTHER = $FXN(..., $QUERY, ...) + ... + $OBJ.QueryRowContext($CTX, $OTHER, ...) + - pattern: | + $QUERY = $X + ... + ... + $OBJ.Exec($QUERY, ...) + - pattern: | + $QUERY = $X + ... + ... + $OBJ.Query($QUERY, ...) + - pattern: | + $QUERY = $X + ... + ... + $OBJ.ExecContext($CTX, $QUERY, ...) + - pattern: | + $QUERY = $X + ... + ... + $OBJ.QueryContext($CTX, $QUERY, ...) + - pattern: | + $QUERY = $X + ... + ... + $OBJ.QueryRow($QUERY) + - pattern: | + $QUERY = $X + ... + ... + $OBJ.QueryRow($CTX, $QUERY) + - pattern: | + $QUERY = $X + ... + ... + $OBJ.QueryRowContext($CTX, $QUERY, ...) diff --git a/tests/semgrep/go/lang/security/audit/md5-used-as-password.yaml b/tests/semgrep/go/lang/security/audit/md5-used-as-password.yaml new file mode 100644 index 0000000..d0b9923 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/md5-used-as-password.yaml @@ -0,0 +1,35 @@ +rules: + - id: md5-used-as-password + languages: [go] + severity: WARNING + message: >- + It looks like MD5 is used as a password hash. MD5 is not considered a + secure password hash because it can be cracked by an attacker in a short + amount of time. Use a suitable password hashing function such as bcrypt. + You can use the `golang.org/x/crypto/bcrypt` package. + metadata: + category: security + technology: + - md5 + references: + - https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html + - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords + - https://github.com/returntocorp/semgrep-rules/issues/1609 + - https://pkg.go.dev/golang.org/x/crypto/bcrypt + owasp: + - A02:2017 - Broken Authentication + - A02:2021 - Cryptographic Failures + cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" + confidence: HIGH + mode: taint + pattern-sources: + - patterns: + - pattern-either: + - pattern: md5.New + - pattern: md5.Sum + pattern-sinks: + - patterns: + - pattern: $FUNCTION(...) + - metavariable-regex: + metavariable: $FUNCTION + regex: (?i)(.*password.*) diff --git a/tests/semgrep/go/lang/security/audit/net/bind_all.yaml b/tests/semgrep/go/lang/security/audit/net/bind_all.yaml new file mode 100644 index 0000000..696828b --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/net/bind_all.yaml @@ -0,0 +1,21 @@ +rules: + - id: avoid-bind-to-all-interfaces + message: >- + Detected a network listener listening on 0.0.0.0 or an empty string. + This could unexpectedly expose the server publicly as it binds to all available interfaces. + Instead, specify another IP address that is not 0.0.0.0 nor the empty string. + languages: [go] + severity: WARNING + metadata: + cwe: "CWE-200: Exposure of Sensitive Information to an Unauthorized Actor" + owasp: "A6: Security Misconfiguration" + source-rule-url: https://github.com/securego/gosec + category: security + technology: + - go + confidence: MEDIUM + pattern-either: + - pattern: tls.Listen($NETWORK, "=~/^0.0.0.0:.*$/", ...) + - pattern: net.Listen($NETWORK, "=~/^0.0.0.0:.*$/", ...) + - pattern: tls.Listen($NETWORK, "=~/^:.*$/", ...) + - pattern: net.Listen($NETWORK, "=~/^:.*$/", ...) \ No newline at end of file diff --git a/tests/semgrep/go/lang/security/audit/net/cookie-missing-httponly.yaml b/tests/semgrep/go/lang/security/audit/net/cookie-missing-httponly.yaml new file mode 100644 index 0000000..50f2440 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/net/cookie-missing-httponly.yaml @@ -0,0 +1,34 @@ +rules: + - id: cookie-missing-httponly + patterns: + - pattern-not-inside: | + http.Cookie{ + ..., + HttpOnly: true, + ..., + } + - pattern: | + http.Cookie{ + ..., + } + message: >- + A session cookie was detected without setting the 'HttpOnly' flag. + The 'HttpOnly' flag for cookies instructs the browser to forbid + client-side scripts from reading the cookie which mitigates XSS + attacks. Set the 'HttpOnly' flag by setting 'HttpOnly' to 'true' + in the Cookie. + metadata: + cwe: "CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag" + owasp: "A3: Sensitive Data Exposure" + references: + - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/util/cookie.go + - https://golang.org/src/net/http/cookie.go + category: security + technology: + - go + confidence: MEDIUM + fix-regex: + regex: (HttpOnly\s*:\s+)false + replacement: \1true + severity: WARNING + languages: [go] diff --git a/tests/semgrep/go/lang/security/audit/net/cookie-missing-secure.yaml b/tests/semgrep/go/lang/security/audit/net/cookie-missing-secure.yaml new file mode 100644 index 0000000..95387b5 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/net/cookie-missing-secure.yaml @@ -0,0 +1,33 @@ +rules: + - id: cookie-missing-secure + patterns: + - pattern-not-inside: | + http.Cookie{ + ..., + Secure: true, + ..., + } + - pattern: | + http.Cookie{ + ..., + } + message: >- + A session cookie was detected without setting the 'Secure' flag. + The 'secure' flag for cookies prevents the client from transmitting + the cookie over insecure channels such as HTTP. Set the 'Secure' + flag by setting 'Secure' to 'true' in the Options struct. + metadata: + cwe: "CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute" + owasp: "A3: Sensitive Data Exposure" + references: + - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/util/cookie.go + - https://golang.org/src/net/http/cookie.go + category: security + technology: + - go + confidence: MEDIUM + fix-regex: + regex: (Secure\s*:\s+)false + replacement: \1true + severity: WARNING + languages: [go] diff --git a/tests/semgrep/go/lang/security/audit/net/dynamic-httptrace-clienttrace.yaml b/tests/semgrep/go/lang/security/audit/net/dynamic-httptrace-clienttrace.yaml new file mode 100644 index 0000000..3e1f803 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/net/dynamic-httptrace-clienttrace.yaml @@ -0,0 +1,32 @@ +rules: + - id: dynamic-httptrace-clienttrace + message: >- + Detected a potentially dynamic ClientTrace. This occurred because semgrep could + not + find a static definition for '$TRACE'. Dynamic ClientTraces are dangerous because + they deserialize function code to run when certain Request events occur, which + could lead + to code being run without your knowledge. Ensure that your ClientTrace is statically + defined. + metadata: + cwe: "CWE-913: Improper Control of Dynamically-Managed Code Resources" + owasp: "A8: Insecure Deserialization" + references: + - https://github.com/returntocorp/semgrep-rules/issues/518 + # Detects when a static ClientTrace is not defined in the same file as + # WithClientTrace. Not a perfect detection, but sufficiently works in a + # scan of ~1k repos: https://dev.massive.ret2.co/triager/filter/1007 + category: security + technology: + - go + confidence: MEDIUM + patterns: + - pattern-not-inside: | + package $PACKAGE + ... + &httptrace.ClientTrace { ... } + ... + - pattern: httptrace.WithClientTrace($ANY, $TRACE) + severity: WARNING + languages: + - go diff --git a/tests/semgrep/go/lang/security/audit/net/formatted-template-string.yaml b/tests/semgrep/go/lang/security/audit/net/formatted-template-string.yaml new file mode 100644 index 0000000..6987592 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/net/formatted-template-string.yaml @@ -0,0 +1,47 @@ +rules: + - id: formatted-template-string + message: >- + Found a formatted template string passed to 'template.HTML()'. + 'template.HTML()' does not escape contents. + Be absolutely sure there is no user-controlled data in this template. + If user data can reach this template, you may have a XSS vulnerability. + metadata: + cwe: "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')" + owasp: "A1: Injection" + references: + - https://golang.org/pkg/html/template/#HTML + category: security + technology: + - go + confidence: MEDIUM + languages: [go] + severity: WARNING + patterns: + - pattern-not: template.HTML("..." + "...") + - pattern-either: + - pattern: template.HTML($T + $X, ...) + - pattern: template.HTML(fmt.$P("...", ...), ...) + - pattern: | + $T = "..." + ... + $T = $FXN(..., $T, ...) + ... + template.HTML($T, ...) + - pattern: | + $T = fmt.$P("...", ...) + ... + template.HTML($T, ...) + - pattern: | + $T, $ERR = fmt.$P("...", ...) + ... + template.HTML($T, ...) + - pattern: | + $T = $X + $Y + ... + template.HTML($T, ...) + - pattern: | + $T = "..." + ... + $OTHER, $ERR = fmt.$P(..., $T, ...) + ... + template.HTML($OTHER, ...) \ No newline at end of file diff --git a/tests/semgrep/go/lang/security/audit/net/pprof.yaml b/tests/semgrep/go/lang/security/audit/net/pprof.yaml new file mode 100644 index 0000000..1b66f32 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/net/pprof.yaml @@ -0,0 +1,35 @@ +rules: + - id: pprof-debug-exposure + metadata: + cwe: "CWE-489: Active Debug Code" + owasp: "A6: Security Misconfiguration" + source-rule-url: https://github.com/securego/gosec#available-rules + references: + - https://www.farsightsecurity.com/blog/txt-record/go-remote-profiling-20161028/ + category: security + technology: + - go + confidence: MEDIUM + message: >- + The profiling 'pprof' endpoint is automatically exposed on /debug/pprof. + This could leak information about the server. + Instead, use `import "net/http/pprof"`. See + https://www.farsightsecurity.com/blog/txt-record/go-remote-profiling-20161028/ + for more information and mitigation. + languages: [go] + severity: WARNING + patterns: + - pattern-inside: | + import _ "net/http/pprof" + ... + - pattern-inside: | + func $ANY(...) { + ... + } + - pattern-not-inside: | + $MUX = http.NewServeMux(...) + ... + http.ListenAndServe($ADDR, $MUX) + - pattern-not: http.ListenAndServe("=~/^localhost.*/", ...) + - pattern-not: http.ListenAndServe("=~/^127[.]0[.]0[.]1.*/", ...) + - pattern: http.ListenAndServe(...) diff --git a/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-htmlattr.yaml b/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-htmlattr.yaml new file mode 100644 index 0000000..0c3235d --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-htmlattr.yaml @@ -0,0 +1,47 @@ +rules: + - id: unescaped-data-in-htmlattr + message: >- + Found a formatted template string passed to 'template. + HTMLAttr()'. 'template.HTMLAttr()' does not escape contents. + Be absolutely sure there is no user-controlled data in this template or + validate and sanitize the data before passing it into the template. + metadata: + cwe: + "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ + \ Scripting')" + owasp: "A1: Injection" + references: + - https://golang.org/pkg/html/template/#HTMLAttr + category: security + technology: + - go + confidence: MEDIUM + languages: [go] + severity: WARNING + pattern-either: + - pattern: template.HTMLAttr($T + $X, ...) + - pattern: template.HTMLAttr(fmt.$P("...", ...), ...) + - pattern: | + $T = "..." + ... + $T = $FXN(..., $T, ...) + ... + template.HTMLAttr($T, ...) + - pattern: | + $T = fmt.$P("...", ...) + ... + template.HTMLAttr($T, ...) + - pattern: | + $T, $ERR = fmt.$P("...", ...) + ... + template.HTMLAttr($T, ...) + - pattern: | + $T = $X + $Y + ... + template.HTMLAttr($T, ...) + - pattern: | + $T = "..." + ... + $OTHER, $ERR = fmt.$P(..., $T, ...) + ... + template.HTMLAttr($OTHER, ...) \ No newline at end of file diff --git a/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-js.yaml b/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-js.yaml new file mode 100644 index 0000000..3c7ed7e --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-js.yaml @@ -0,0 +1,46 @@ +rules: + - id: unescaped-data-in-js + message: >- + Found a formatted template string passed to 'template.JS()'. + 'template.JS()' does not escape contents. Be absolutely sure + there is no user-controlled data in this template. + metadata: + cwe: + "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ + \ Scripting')" + owasp: "A1: Injection" + references: + - https://golang.org/pkg/html/template/#JS + category: security + technology: + - go + confidence: MEDIUM + languages: [go] + severity: WARNING + pattern-either: + - pattern: template.JS($T + $X, ...) + - pattern: template.JS(fmt.$P("...", ...), ...) + - pattern: | + $T = "..." + ... + $T = $FXN(..., $T, ...) + ... + template.JS($T, ...) + - pattern: | + $T = fmt.$P("...", ...) + ... + template.JS($T, ...) + - pattern: | + $T, $ERR = fmt.$P("...", ...) + ... + template.JS($T, ...) + - pattern: | + $T = $X + $Y + ... + template.JS($T, ...) + - pattern: | + $T = "..." + ... + $OTHER, $ERR = fmt.$P(..., $T, ...) + ... + template.JS($OTHER, ...) diff --git a/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-url.yaml b/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-url.yaml new file mode 100644 index 0000000..a9bc14b --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-url.yaml @@ -0,0 +1,48 @@ +rules: + - id: unescaped-data-in-url + message: >- + Found a formatted template string passed to 'template.URL()'. + 'template.URL()' does not escape contents, and this could result in XSS (cross-site scripting) + and therefore confidential data being stolen. + Sanitize data coming into this function or make sure that + no user-controlled input is coming into the function. + metadata: + cwe: + "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ + \ Scripting')" + owasp: "A1: Injection" + references: + - https://golang.org/pkg/html/template/#URL + category: security + technology: + - go + confidence: MEDIUM + languages: [go] + severity: WARNING + pattern-either: + - pattern: template.URL($T + $X, ...) + - pattern: template.URL(fmt.$P("...", ...), ...) + - pattern: | + $T = "..." + ... + $T = $FXN(..., $T, ...) + ... + template.URL($T, ...) + - pattern: | + $T = fmt.$P("...", ...) + ... + template.URL($T, ...) + - pattern: | + $T, $ERR = fmt.$P("...", ...) + ... + template.URL($T, ...) + - pattern: | + $T = $X + $Y + ... + template.URL($T, ...) + - pattern: | + $T = "..." + ... + $OTHER, $ERR = fmt.$P(..., $T, ...) + ... + template.URL($OTHER, ...) \ No newline at end of file diff --git a/tests/semgrep/go/lang/security/audit/net/use-tls.yaml b/tests/semgrep/go/lang/security/audit/net/use-tls.yaml new file mode 100644 index 0000000..ecba4b5 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/net/use-tls.yaml @@ -0,0 +1,18 @@ +rules: + - id: use-tls + pattern: http.ListenAndServe($ADDR, $HANDLER) + fix: http.ListenAndServeTLS($ADDR, certFile, keyFile, $HANDLER) + metadata: + cwe: "CWE-319: Cleartext Transmission of Sensitive Information" + owasp: "A3: Sensitive Data Exposure" + references: + - https://golang.org/pkg/net/http/#ListenAndServeTLS + category: security + technology: + - go + confidence: MEDIUM + message: >- + Found an HTTP server without TLS. Use 'http.ListenAndServeTLS' instead. + See https://golang.org/pkg/net/http/#ListenAndServeTLS for more information. + languages: [go] + severity: WARNING diff --git a/tests/semgrep/go/lang/security/audit/net/wip-xss-using-responsewriter-and-printf.yaml b/tests/semgrep/go/lang/security/audit/net/wip-xss-using-responsewriter-and-printf.yaml new file mode 100644 index 0000000..5692cc5 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/net/wip-xss-using-responsewriter-and-printf.yaml @@ -0,0 +1,61 @@ +rules: + - id: wip-xss-using-responsewriter-and-printf + patterns: + - pattern-inside: | + func $FUNC(..., $W http.ResponseWriter, ...) { + ... + var $TEMPLATE = "..." + ... + $W.Write([]byte(fmt.$PRINTF($TEMPLATE, ...)), ...) + ... + } + - pattern-either: + - pattern: | + $PARAMS = r.URL.Query() + ... + $DATA, $ERR := $PARAMS[...] + ... + $INTERM = $ANYTHING(..., $DATA, ...) + ... + $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) + - pattern: | + $PARAMS = r.URL.Query() + ... + $DATA, $ERR := $PARAMS[...] + ... + $INTERM = $DATA[...] + ... + $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) + - pattern: | + $DATA, $ERR := r.URL.Query()[...] + ... + $INTERM = $DATA[...] + ... + $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) + - pattern: | + $DATA, $ERR := r.URL.Query()[...] + ... + $INTERM = $ANYTHING(..., $DATA, ...) + ... + $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) + - pattern: | + $PARAMS = r.URL.Query() + ... + $DATA, $ERR := $PARAMS[...] + ... + $W.Write([]byte(fmt.$PRINTF(..., $DATA, ...))) + message: >- + Found data going from url query parameters into formatted data written to ResponseWriter. + This could be XSS and should not be done. If you must do this, ensure your data + is + sanitized or escaped. + metadata: + cwe: "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')" + owasp: "A7: Cross-Site Scripting (XSS)" + category: security + technology: + - go + confidence: MEDIUM + severity: WARNING + languages: + - go diff --git a/tests/semgrep/go/lang/security/audit/reflect-makefunc.yaml b/tests/semgrep/go/lang/security/audit/reflect-makefunc.yaml new file mode 100644 index 0000000..87a8407 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/reflect-makefunc.yaml @@ -0,0 +1,18 @@ +rules: + - id: reflect-makefunc + message: >- + 'reflect.MakeFunc' detected. This will sidestep protections that are + normally afforded by Go's type system. Audit this call and be sure that + user input cannot be used to affect the code generated by MakeFunc; + otherwise, you will have a serious security vulnerability. + metadata: + owasp: "A8: Insecure Deserialization" + cwe: "CWE-913: Improper Control of Dynamically-Managed Code Resources" + category: security + technology: + - go + confidence: MEDIUM + severity: ERROR + pattern: reflect.MakeFunc(...) + languages: + - go diff --git a/tests/semgrep/go/lang/security/audit/sqli/gosql-sqli.yaml b/tests/semgrep/go/lang/security/audit/sqli/gosql-sqli.yaml new file mode 100644 index 0000000..a4c9dfd --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/sqli/gosql-sqli.yaml @@ -0,0 +1,52 @@ +rules: + - id: gosql-sqli + patterns: + - pattern-either: + - patterns: + - pattern: $DB.$METHOD(...,$QUERY,...) + - pattern-either: + - pattern-inside: | + $QUERY = $X + $Y + ... + - pattern-inside: | + $QUERY += $X + ... + - pattern-inside: | + $QUERY = fmt.Sprintf("...", $PARAM1, ...) + ... + - pattern-not-inside: | + $QUERY += "..." + ... + - pattern-not-inside: | + $QUERY = "..." + "..." + ... + - pattern: $DB.$METHOD(..., $X + $Y, ...) + - pattern: $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...) + - pattern-either: + - pattern-inside: | + $DB, ... = sql.Open(...) + ... + - pattern-inside: | + func $FUNCNAME(..., $DB *sql.DB, ...) { + ... + } + - pattern-not: $DB.$METHOD(..., "..." + "...", ...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(Exec|ExecContent|Query|QueryContext|QueryRow|QueryRowContext)$ + languages: + - go + message: >- + Detected string concatenation with a non-literal variable in a "database/sql" + Go SQL statement. This could lead to SQL injection if the variable is user-controlled + and not properly sanitized. In order to prevent SQL injection, + used parameterized queries or prepared statements instead. + You can use prepared statements with the 'Prepare' and 'PrepareContext' calls. + metadata: + references: + - https://golang.org/pkg/database/sql/ + category: security + technology: + - go + confidence: MEDIUM + severity: ERROR diff --git a/tests/semgrep/go/lang/security/audit/sqli/pg-orm-sqli.yaml b/tests/semgrep/go/lang/security/audit/sqli/pg-orm-sqli.yaml new file mode 100644 index 0000000..085758b --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/sqli/pg-orm-sqli.yaml @@ -0,0 +1,55 @@ +rules: + - id: pg-orm-sqli + patterns: + - pattern-either: + - patterns: + - pattern: $DB.$METHOD(...,$QUERY,...) + - pattern-either: + - pattern-inside: | + $QUERY = $X + $Y + ... + - pattern-inside: | + $QUERY += $X + ... + - pattern-inside: | + $QUERY = fmt.Sprintf("...", $PARAM1, ...) + ... + - pattern-not-inside: | + $QUERY += "..." + ... + - pattern-not-inside: | + $QUERY = "..." + "..." + ... + - pattern: | + $DB.$INTFUNC1(...).$METHOD(..., $X + $Y, ...).$INTFUNC2(...) + - pattern: | + $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...) + - pattern-inside: | + $DB = pg.Connect(...) + ... + - pattern-inside: | + func $FUNCNAME(..., $DB *pg.DB, ...) { + ... + } + - pattern-not: | + $DB.$INTFUNC1(...).$METHOD(..., "..." + "...", ...).$INTFUNC2(...) + - pattern-not: path.Join(...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(Where|WhereOr|Join|GroupExpr|OrderExpr|ColumnExpr)$ + languages: + - go + message: >- + Detected string concatenation with a non-literal variable in a go-pg ORM + SQL statement. This could lead to SQL injection if the variable is user-controlled + and not properly sanitized. In order to prevent SQL injection, + do not use strings concatenated with user-controlled input. + Instead, use parameterized statements. + metadata: + references: + - https://pg.uptrace.dev/queries/ + category: security + technology: + - go-pg + confidence: MEDIUM + severity: ERROR diff --git a/tests/semgrep/go/lang/security/audit/sqli/pg-sqli.yaml b/tests/semgrep/go/lang/security/audit/sqli/pg-sqli.yaml new file mode 100644 index 0000000..0454374 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/sqli/pg-sqli.yaml @@ -0,0 +1,55 @@ +rules: + - id: pg-sqli + languages: + - go + message: >- + Detected string concatenation with a non-literal variable in a go-pg + SQL statement. This could lead to SQL injection if the variable is user-controlled + and not properly sanitized. In order to prevent SQL injection, + used parameterized queries instead of string concatenation. You can use parameterized + queries like so: + '(SELECT ? FROM table, data1)' + metadata: + references: + - https://pg.uptrace.dev/ + - https://pkg.go.dev/github.com/go-pg/pg/v10 + category: security + technology: + - go-pg + confidence: MEDIUM + severity: ERROR + patterns: + - pattern-either: + - patterns: + - pattern: | + $DB.$METHOD(...,$QUERY,...) + - pattern-either: + - pattern-inside: | + $QUERY = $X + $Y + ... + - pattern-inside: | + $QUERY += $X + ... + - pattern-inside: | + $QUERY = fmt.Sprintf("...", $PARAM1, ...) + ... + - pattern-not-inside: | + $QUERY += "..." + ... + - pattern-not-inside: | + $QUERY = "..." + "..." + ... + - pattern: $DB.$METHOD(..., $X + $Y, ...) + - pattern: $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...) + - pattern-either: + - pattern-inside: | + $DB = pg.Connect(...) + ... + - pattern-inside: | + func $FUNCNAME(..., $DB *pg.DB, ...) { + ... + } + - pattern-not: $DB.$METHOD(..., "..." + "...", ...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(Exec|ExecContext|ExecOne|ExecOneContext|Query|QueryOne|QueryContext|QueryOneContext)$ diff --git a/tests/semgrep/go/lang/security/audit/sqli/pgx-sqli.yaml b/tests/semgrep/go/lang/security/audit/sqli/pgx-sqli.yaml new file mode 100644 index 0000000..24bba65 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/sqli/pgx-sqli.yaml @@ -0,0 +1,59 @@ +rules: + - id: pgx-sqli + languages: + - go + message: >- + Detected string concatenation with a non-literal variable in a pgx + Go SQL statement. This could lead to SQL injection if the variable is user-controlled + and not properly sanitized. In order to prevent SQL injection, + used parameterized queries instead. You can use parameterized queries like so: + (`SELECT $1 FROM table`, `data1) + metadata: + references: + - https://github.com/jackc/pgx + - https://pkg.go.dev/github.com/jackc/pgx/v4#hdr-Connection_Pool + category: security + technology: + - pgx + confidence: MEDIUM + patterns: + - pattern-either: + - patterns: + - pattern: $DB.$METHOD(...,$QUERY,...) + - pattern-either: + - pattern-inside: | + $QUERY = $X + $Y + ... + - pattern-inside: | + $QUERY += $X + ... + - pattern-inside: | + $QUERY = fmt.Sprintf("...", $PARAM1, ...) + ... + - pattern-not-inside: | + $QUERY += "..." + ... + - pattern-not-inside: | + $QUERY = "..." + "..." + ... + - pattern: $DB.$METHOD(..., $X + $Y, ...) + - pattern: $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...) + - pattern-either: + - pattern-inside: | + $DB, ... = pgx.Connect(...) + ... + - pattern-inside: | + $DB, ... = pgx.NewConnPool(...) + ... + - pattern-inside: | + $DB, ... = pgx.ConnectConfig(...) + ... + - pattern-inside: | + func $FUNCNAME(..., $DB *pgx.Conn, ...) { + ... + } + - pattern-not: $DB.$METHOD(..., "..." + "...", ...) + - metavariable-regex: + metavariable: $METHOD + regex: ^(Exec|ExecEx|Query|QueryEx|QueryRow|QueryRowEx)$ + severity: ERROR diff --git a/tests/semgrep/go/lang/security/audit/unsafe-reflect-by-name.yaml b/tests/semgrep/go/lang/security/audit/unsafe-reflect-by-name.yaml new file mode 100644 index 0000000..0bddd02 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/unsafe-reflect-by-name.yaml @@ -0,0 +1,34 @@ +rules: + - id: unsafe-reflect-by-name + patterns: + - pattern-either: + - pattern: | + $SMTH.MethodByName($NAME,...) + - pattern: | + $SMTH.FieldByName($NAME,...) + - pattern-not: | + $SMTH.MethodByName("...",...) + - pattern-not: | + $SMTH.FieldByName("...",...) + - pattern-inside: | + import "reflect" + ... + message: >- + If an attacker can supply values that the application then uses to determine which + method or field to invoke, + the potential exists for the attacker to create control flow paths through the + application + that were not intended by the application developers. + This attack vector may allow the attacker to bypass authentication or access control + checks + or otherwise cause the application to behave in an unexpected manner. + metadata: + cwe: "CWE-470: Use of Externally-Controlled Input to Select Classes or Code ('Unsafe Reflection')" + owasp: "A1: Injection" + category: security + technology: + - go + confidence: MEDIUM + severity: WARNING + languages: + - go diff --git a/tests/semgrep/go/lang/security/audit/unsafe.yaml b/tests/semgrep/go/lang/security/audit/unsafe.yaml new file mode 100644 index 0000000..864f165 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/unsafe.yaml @@ -0,0 +1,17 @@ +rules: + - id: use-of-unsafe-block + message: >- + Using the unsafe package in Go gives you low-level memory management + and many of the strengths of the C language, but also steps around the type safety of Go + and can lead to buffer overflows and possible arbitrary code execution by an attacker. + Only use this package if you absolutely know what you're doing. + languages: [go] + severity: WARNING + metadata: + cwe: "CWE-242: Use of Inherently Dangerous Function" + source_rule_url: https://github.com/securego/gosec/blob/master/rules/unsafe.go + category: security + technology: + - go + confidence: MEDIUM + pattern: unsafe.$FUNC(...) diff --git a/tests/semgrep/go/lang/security/audit/xss/import-text-template.yaml b/tests/semgrep/go/lang/security/audit/xss/import-text-template.yaml new file mode 100644 index 0000000..99faa68 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/xss/import-text-template.yaml @@ -0,0 +1,21 @@ +rules: + - id: import-text-template + message: >- + 'text/template' does not escape HTML content. If you need + to escape HTML content, use 'html/template' instead. + metadata: + owasp: "A7: Cross-Site Scripting (XSS)" + cwe: + "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ + \ Scripting')" + references: + - https://www.veracode.com/blog/secure-development/use-golang-these-mistakes-could-compromise-your-apps-security + category: security + technology: + - go + confidence: MEDIUM + severity: WARNING + pattern: | + import "text/template" + languages: + - go diff --git a/tests/semgrep/go/lang/security/audit/xss/no-direct-write-to-responsewriter.yaml b/tests/semgrep/go/lang/security/audit/xss/no-direct-write-to-responsewriter.yaml new file mode 100644 index 0000000..ea22ad1 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/xss/no-direct-write-to-responsewriter.yaml @@ -0,0 +1,40 @@ +rules: + - id: no-direct-write-to-responsewriter + languages: + - go + message: >- + Detected directly writing or similar in 'http.ResponseWriter.write()'. + This bypasses HTML escaping that prevents cross-site scripting + vulnerabilities. Instead, use the 'html/template' package + and render data using 'template.Execute()'. + metadata: + category: security + cwe: + "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ + \ Scripting')" + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + owasp: "A7: Cross-Site Scripting (XSS)" + references: + - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ + technology: + - go + confidence: MEDIUM + patterns: + - pattern-either: + - pattern-inside: | + func $HANDLER(..., $WRITER http.ResponseWriter, ...) { + ... + } + - pattern-inside: | + func $HANDLER(..., $WRITER *http.ResponseWriter, ...) { + ... + } + - pattern-inside: | + func(..., $WRITER http.ResponseWriter, ...) { + ... + } + - pattern-either: + - pattern: $WRITER.Write(...) + - pattern: (*$WRITER).Write(...) + - pattern-not: $WRITER.Write([]byte("...")) + severity: WARNING diff --git a/tests/semgrep/go/lang/security/audit/xss/no-fprintf-to-responsewriter.yaml b/tests/semgrep/go/lang/security/audit/xss/no-fprintf-to-responsewriter.yaml new file mode 100644 index 0000000..a990aaa --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/xss/no-fprintf-to-responsewriter.yaml @@ -0,0 +1,33 @@ +rules: + - id: no-fprintf-to-responsewriter + message: >- + Detected 'Fprintf' or similar writing to 'http.ResponseWriter'. + This bypasses HTML escaping that prevents cross-site scripting + vulnerabilities. Instead, use the 'html/template' package + to render data to users. + metadata: + owasp: "A7: Cross-Site Scripting (XSS)" + cwe: + "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ + \ Scripting')" + references: + - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ + category: security + technology: + - go + confidence: MEDIUM + severity: WARNING + patterns: + - pattern-either: + - pattern-inside: | + func $HANDLER(..., $WRITER http.ResponseWriter, ...) { + ... + } + - pattern-inside: | + func(..., $WRITER http.ResponseWriter, ...) { + ... + } + - pattern-not: fmt.$PRINTF($WRITER, "...") + - pattern: fmt.$PRINTF($WRITER, ...) + languages: + - go diff --git a/tests/semgrep/go/lang/security/audit/xss/no-interpolation-in-tag.yaml b/tests/semgrep/go/lang/security/audit/xss/no-interpolation-in-tag.yaml new file mode 100644 index 0000000..f205a70 --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/xss/no-interpolation-in-tag.yaml @@ -0,0 +1,24 @@ +rules: + - id: no-interpolation-in-tag + message: >- + Detected template variable interpolation in an HTML tag. + This is potentially vulnerable to cross-site scripting (XSS) + attacks because a malicious actor has control over HTML + but without the need to use escaped characters. Use explicit + tags instead. + metadata: + cwe: + "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ + \ Scripting')" + owasp: "A7: Cross-Site Scripting (XSS)" + references: + - https://github.com/golang/go/issues/19669 + - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ + category: security + technology: + - generic + confidence: MEDIUM + languages: + - generic + severity: WARNING + pattern: <{{ ... }} ... > diff --git a/tests/semgrep/go/lang/security/audit/xss/no-interpolation-js-template-string.yaml b/tests/semgrep/go/lang/security/audit/xss/no-interpolation-js-template-string.yaml new file mode 100644 index 0000000..7a193db --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/xss/no-interpolation-js-template-string.yaml @@ -0,0 +1,28 @@ +rules: + - id: no-interpolation-js-template-string + message: >- + Detected template variable interpolation in a JavaScript + template string. This is potentially vulnerable to + cross-site scripting (XSS) attacks because a malicious + actor has control over JavaScript but without the need + to use escaped characters. Instead, obtain this variable + outside of the template string and ensure your template + is properly escaped. + metadata: + cwe: + "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ + \ Scripting')" + owasp: "A7: Cross-Site Scripting (XSS)" + references: + - https://github.com/golang/go/issues/9200#issuecomment-66100328 + - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ + category: security + technology: + - generic + confidence: MEDIUM + languages: + - generic + severity: WARNING + patterns: + - pattern-inside: + - pattern: "` ... {{ ... }} ...`" diff --git a/tests/semgrep/go/lang/security/audit/xss/no-io-writestring-to-responsewriter.yaml b/tests/semgrep/go/lang/security/audit/xss/no-io-writestring-to-responsewriter.yaml new file mode 100644 index 0000000..77edbbd --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/xss/no-io-writestring-to-responsewriter.yaml @@ -0,0 +1,34 @@ +rules: + - id: no-io-writestring-to-responsewriter + message: >- + Detected 'io.WriteString()' writing directly to 'http.ResponseWriter'. + This bypasses HTML escaping that prevents cross-site scripting + vulnerabilities. Instead, use the 'html/template' package + to render data to users. + metadata: + owasp: "A7: Cross-Site Scripting (XSS)" + cwe: + "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ + \ Scripting')" + references: + - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ + - https://golang.org/pkg/io/#WriteString + category: security + technology: + - go + confidence: MEDIUM + severity: WARNING + patterns: + - pattern-either: + - pattern-inside: | + func $HANDLER(..., $WRITER http.ResponseWriter, ...) { + ... + } + - pattern-inside: | + func(..., $WRITER http.ResponseWriter, ...) { + ... + } + - pattern-not: io.WriteString($WRITER, "...") + - pattern: io.WriteString($WRITER, $STRING) + languages: + - go diff --git a/tests/semgrep/go/lang/security/audit/xss/no-printf-in-responsewriter.yaml b/tests/semgrep/go/lang/security/audit/xss/no-printf-in-responsewriter.yaml new file mode 100644 index 0000000..6e8790c --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/xss/no-printf-in-responsewriter.yaml @@ -0,0 +1,33 @@ +rules: + - id: no-printf-in-responsewriter + message: >- + Detected 'printf' or similar in 'http.ResponseWriter.write()'. + This bypasses HTML escaping that prevents cross-site scripting + vulnerabilities. Instead, use the 'html/template' package + to render data to users. + metadata: + owasp: "A7: Cross-Site Scripting (XSS)" + cwe: + "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ + \ Scripting')" + references: + - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ + category: security + technology: + - go + confidence: MEDIUM + severity: WARNING + patterns: + - pattern-either: + - pattern-inside: | + func $HANDLER(..., $WRITER http.ResponseWriter, ...) { + ... + } + - pattern-inside: | + func(..., $WRITER http.ResponseWriter, ...) { + ... + } + - pattern: | + $WRITER.Write(<... fmt.$PRINTF(...) ...>, ...) + languages: + - go diff --git a/tests/semgrep/go/lang/security/audit/xss/template-html-does-not-escape.yaml b/tests/semgrep/go/lang/security/audit/xss/template-html-does-not-escape.yaml new file mode 100644 index 0000000..aa5c2cf --- /dev/null +++ b/tests/semgrep/go/lang/security/audit/xss/template-html-does-not-escape.yaml @@ -0,0 +1,34 @@ +rules: + - id: unsafe-template-type + message: >- + Semgrep could not determine that the argument to 'template.HTML()' + is a constant. 'template.HTML()' and similar does not escape contents. + Be absolutely sure there is no user-controlled data in this + template. If user data can reach this template, you may have + a XSS vulnerability. Instead, do not use this function and + use 'template.Execute()'. + metadata: + cwe: + "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ + \ Scripting')" + owasp: "A7: Cross-Site Scripting (XSS)" + references: + - https://golang.org/pkg/html/template/#HTML + - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/vulnerability/xss/xss.go#L33 + category: security + technology: + - go + confidence: MEDIUM + languages: [go] + severity: WARNING + patterns: + - pattern-not: template.$ANY("..." + "...") + - pattern-not: template.$ANY("...") + - pattern-either: + - pattern: template.HTML(...) + - pattern: template.CSS(...) + - pattern: template.HTMLAttr(...) + - pattern: template.JS(...) + - pattern: template.JSStr(...) + - pattern: template.Srcset(...) + - pattern: template.URL(...) diff --git a/tests/semgrep/go/lang/security/bad_tmp.yaml b/tests/semgrep/go/lang/security/bad_tmp.yaml new file mode 100644 index 0000000..046abde --- /dev/null +++ b/tests/semgrep/go/lang/security/bad_tmp.yaml @@ -0,0 +1,15 @@ +rules: + - id: bad-tmp-file-creation + message: File creation in shared tmp directory without using ioutil.Tempfile + languages: [go] + severity: WARNING + metadata: + cwe: "CWE-377: Insecure Temporary File" + source-rule-url: https://github.com/securego/gosec + category: security + technology: + - go + confidence: MEDIUM + pattern-either: + - pattern: ioutil.WriteFile("=~//tmp/.*$/", ...) + - pattern: os.Create("=~//tmp/.*$/", ...) diff --git a/tests/semgrep/go/lang/security/decompression_bomb.yaml b/tests/semgrep/go/lang/security/decompression_bomb.yaml new file mode 100644 index 0000000..fc34332 --- /dev/null +++ b/tests/semgrep/go/lang/security/decompression_bomb.yaml @@ -0,0 +1,59 @@ +rules: + - id: potential-dos-via-decompression-bomb + message: >- + Detected a possible denial-of-service via a zip bomb attack. By limiting the max + bytes read, you can mitigate this attack. + `io.CopyN()` can specify a size. Refer to https://bomb.codes/ to learn more about + this attack and other ways to mitigate + it. + severity: WARNING + languages: [go] + patterns: + - pattern-either: + - pattern: io.Copy(...) + - pattern: io.CopyBuffer(...) + - pattern-either: + - pattern-inside: | + gzip.NewReader(...) + ... + - pattern-inside: | + zlib.NewReader(...) + ... + - pattern-inside: | + zlib.NewReaderDict(...) + ... + - pattern-inside: | + bzip2.NewReader(...) + ... + - pattern-inside: | + flate.NewReader(...) + ... + - pattern-inside: | + flate.NewReaderDict(...) + ... + - pattern-inside: | + lzw.NewReader(...) + ... + - pattern-inside: | + tar.NewReader(...) + ... + - pattern-inside: | + zip.NewReader(...) + ... + - pattern-inside: | + zip.OpenReader(...) + ... + fix-regex: + regex: (.*)(Copy|CopyBuffer)\((.*?),(.*?)(\)|,.*\)) + replacement: \1CopyN(\3, \4, 1024*1024*256) + metadata: + cwe: "CWE-400: Uncontrolled Resource Consumption" + source-rule-url: https://github.com/securego/gosec + references: + - https://bomb.codes/ + - https://golang.org/pkg/io/#CopyN + - https://github.com/securego/gosec/blob/master/rules/decompression-bomb.go + category: security + technology: + - go + confidence: MEDIUM diff --git a/tests/semgrep/go/lang/security/filepath-clean-misuse.yaml b/tests/semgrep/go/lang/security/filepath-clean-misuse.yaml new file mode 100644 index 0000000..e72f698 --- /dev/null +++ b/tests/semgrep/go/lang/security/filepath-clean-misuse.yaml @@ -0,0 +1,41 @@ +rules: +- id: filepath-clean-misuse + message: >- + `Clean` is not intended to sanitize against path traversal attacks. + This function is for finding the shortest path name equivalent to the given input. + Using `Clean` to sanitize file reads may expose this application to + path traversal attacks, where an attacker could access arbitrary files on the server. + To fix this easily, write this: `filepath.FromSlash(path.Clean("/"+strings.Trim(req.URL.Path, "/")))` + However, a better solution is using the `SecureJoin` function in the package `filepath-securejoin`. + See https://pkg.go.dev/github.com/cyphar/filepath-securejoin#section-readme. + severity: ERROR + languages: [go] + mode: taint + pattern-sources: + - pattern-either: + - pattern: "($REQUEST : *http.Request).$ANYTHING" + - pattern: "($REQUEST : http.Request).$ANYTHING" + pattern-sinks: + - patterns: + - pattern-either: + - pattern: filepath.Clean($...INNER) + - pattern: path.Clean($...INNER) + pattern-sanitizers: + - pattern-either: + - pattern: | + "/" + ... + fix: filepath.FromSlash(filepath.Clean("/"+strings.Trim($...INNER, "/"))) + metadata: + references: + - https://pkg.go.dev/path#Clean + - http://technosophos.com/2016/03/31/go-quickly-cleaning-filepaths.html + - https://labs.detectify.com/2021/12/15/zero-day-path-traversal-grafana/ + - https://dzx.cz/2021/04/02/go_path_traversal/ + - https://pkg.go.dev/github.com/cyphar/filepath-securejoin#section-readme + cwe: 'CWE-22: Path Traversal' + owasp: + - 'A03:2021 - Injection' + - 'A01:2017 - Injection' + category: security + technology: + - go diff --git a/tests/semgrep/go/lang/security/injection/raw-html-format.yaml b/tests/semgrep/go/lang/security/injection/raw-html-format.yaml new file mode 100644 index 0000000..1e6abab --- /dev/null +++ b/tests/semgrep/go/lang/security/injection/raw-html-format.yaml @@ -0,0 +1,47 @@ +rules: + - id: raw-html-format + languages: [go] + severity: WARNING + message: >- + Detected user input flowing into a manually constructed HTML string. You may be + accidentally bypassing secure methods + of rendering HTML by manually constructing HTML and this could create a cross-site + scripting vulnerability, which could + let attackers steal sensitive user data. Use the `html/template` package which + will safely render HTML instead, or inspect + that the HTML is rendered safely. + metadata: + cwe: + "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ + \ Scripting')" + owasp: + - A07:2017 + - A03:2021 + category: security + technology: + - go + references: + - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: HIGH + mode: taint + pattern-sanitizers: + - pattern: html.EscapeString(...) + pattern-sources: + - patterns: + - pattern-either: + - pattern: "($REQUEST : *http.Request).$ANYTHING" + - pattern: "($REQUEST : http.Request).$ANYTHING" + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: fmt.Printf("$HTMLSTR", ...) + - pattern: fmt.Sprintf("$HTMLSTR", ...) + - pattern: fmt.Fprintf($W, "$HTMLSTR", ...) + - pattern: '"$HTMLSTR" + ...' + - metavariable-pattern: + metavariable: $HTMLSTR + language: generic + pattern: <$TAG ... diff --git a/tests/semgrep/go/lang/security/injection/tainted-sql-string.yaml b/tests/semgrep/go/lang/security/injection/tainted-sql-string.yaml new file mode 100644 index 0000000..80dc91c --- /dev/null +++ b/tests/semgrep/go/lang/security/injection/tainted-sql-string.yaml @@ -0,0 +1,50 @@ +rules: + - id: tainted-sql-string + languages: [go] + message: >- + User data flows into this manually-constructed SQL string. User data + can be safely inserted into SQL strings using prepared statements or an + object-relational mapper (ORM). Manually-constructed SQL strings is a + possible indicator of SQL injection, which could let an attacker steal + or manipulate data from the database. + Instead, use prepared statements (`db.Query("SELECT * FROM t WHERE id = ?", id)`) + or a safe library. + metadata: + cwe: + "CWE-89: Improper Neutralization of Special Elements used in an SQL Command\ + \ ('SQL Injection')" + owasp: + - A10:2021 + - A01:2017 + references: + - https://golang.org/doc/database/sql-injection + - https://www.stackhawk.com/blog/golang-sql-injection-guide-examples-and-prevention/ + category: security + technology: + - go + confidence: HIGH + mode: taint + severity: WARNING + pattern-sources: + - pattern-either: + - pattern: "($REQUEST : *http.Request).$ANYTHING" + - pattern: "($REQUEST : http.Request).$ANYTHING" + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern: | + "$SQLSTR" + ... + - metavariable-regex: + metavariable: $SQLSTR + regex: (?i)(select|delete|insert|create|update|alter|drop).* + - patterns: + - pattern-either: + - pattern: fmt.Fprintf($F, "$SQLSTR", ...) + - pattern: fmt.Sprintf("$SQLSTR", ...) + - pattern: fmt.Printf("$SQLSTR", ...) + - metavariable-regex: + metavariable: $SQLSTR + regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.*%(v|s|q).* + pattern-sanitizers: + - pattern: strconv.Atoi(...) diff --git a/tests/semgrep/go/lang/security/injection/tainted-url-host.yaml b/tests/semgrep/go/lang/security/injection/tainted-url-host.yaml new file mode 100644 index 0000000..9df1aee --- /dev/null +++ b/tests/semgrep/go/lang/security/injection/tainted-url-host.yaml @@ -0,0 +1,46 @@ +rules: + - id: tainted-url-host + languages: + - go + message: + User data flows into the host portion of this manually-constructed URL. + This could allow an attacker to send data to their own server, potentially exposing + sensitive data such as cookies or authorization information sent with this request. + They could also probe internal servers or other resources that the server runnig + this code can access. (This is called server-side request forgery, or SSRF.) Do + not allow arbitrary hosts. Instead, create an allowlist for approved hosts hardcode + the correct host. + metadata: + cwe: "CWE-918: Server-Side Request Forgery (SSRF)" + owasp: + - A10:2021 + - A01:2017 + references: + - https://goteleport.com/blog/ssrf-attacks/ + category: security + technology: + - go + license: Commons Clause License Condition v1.0[LGPL-2.1-only] + confidence: HIGH + mode: taint + pattern-sinks: + - patterns: + - pattern-either: + - patterns: + - pattern-either: + - pattern: fmt.Fprintf($F, "$URLSTR", ...) + - pattern: fmt.Sprintf("$URLSTR", ...) + - pattern: fmt.Printf("$URLSTR", ...) + - metavariable-regex: + metavariable: $URLSTR + regex: http(s?)://%(v|s|q).* + - patterns: + - pattern: '"$URLSTR" + ...' + - metavariable-regex: + metavariable: $URLSTR + regex: \w+://.* + pattern-sources: + - pattern-either: + - pattern: "($REQUEST : *http.Request).$ANYTHING" + - pattern: "($REQUEST : http.Request).$ANYTHING" + severity: WARNING diff --git a/tests/semgrep/go/lang/security/zip.yaml b/tests/semgrep/go/lang/security/zip.yaml new file mode 100644 index 0000000..8885bd3 --- /dev/null +++ b/tests/semgrep/go/lang/security/zip.yaml @@ -0,0 +1,20 @@ +rules: + - id: path-traversal-inside-zip-extraction + message: File traversal when extracting zip archive + metadata: + cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')" + source_rule_url: https://github.com/securego/gosec/issues/205 + category: security + technology: + - go + confidence: MEDIUM + languages: [go] + severity: WARNING + pattern: | + reader, $ERR := zip.OpenReader($ARCHIVE) + ... + for _, $FILE := range reader.File { + ... + path := filepath.Join($TARGET, $FILE.Name) + ... + } diff --git a/tests/semgrep/go/otto/security/audit/dangerous-execution.yaml b/tests/semgrep/go/otto/security/audit/dangerous-execution.yaml new file mode 100644 index 0000000..1dc547e --- /dev/null +++ b/tests/semgrep/go/otto/security/audit/dangerous-execution.yaml @@ -0,0 +1,24 @@ +rules: + - id: dangerous-execution + message: >- + Detected non-static script inside otto VM. Audit the input to 'VM.Run'. + If unverified user data can reach this call site, this is a code injection + vulnerability. A malicious actor can inject a malicious script to execute + arbitrary code. + metadata: + cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')" + owasp: "A1: Injection" + category: security + technology: + - otto + - vm + confidence: MEDIUM + severity: ERROR + patterns: + - pattern-inside: | + $VM = otto.New(...) + ... + - pattern-not: $VM.Run("...", ...) + - pattern: $VM.Run(...) + languages: + - go diff --git a/tests/semgrep/go/template/security/insecure-types.yaml b/tests/semgrep/go/template/security/insecure-types.yaml new file mode 100644 index 0000000..bc001e9 --- /dev/null +++ b/tests/semgrep/go/template/security/insecure-types.yaml @@ -0,0 +1,26 @@ +rules: + - id: go-insecure-templates + patterns: + - pattern-inside: | + import "html/template" + ... + - pattern-either: + - pattern: var $VAR template.HTML = $EXP + - pattern: var $VAR template.CSS = $EXP + - pattern: var $VAR template.HTMLAttr = $EXP + - pattern: var $VAR template.JS = $EXP + - pattern: var $VAR template.JSStr = $EXP + - pattern: var $VAR template.Srcset = $EXP + message: >- + usage of insecure template types. They are documented as a security risk. See https://golang.org/pkg/html/template/#HTML. + severity: WARNING + metadata: + references: + - https://golang.org/pkg/html/template/#HTML + - https://twitter.com/empijei/status/1275177219011350528 + category: security + technology: + - template + confidence: MEDIUM + languages: + - go From a15d63c63e4e536ba2445c88cde7cae0e6cc9ac0 Mon Sep 17 00:00:00 2001 From: eikendev Date: Sun, 13 Feb 2022 16:08:42 +0100 Subject: [PATCH 03/17] Install Poetry in GitHub Workflows --- .github/workflows/documentation.yml | 3 + .github/workflows/main.yml | 8 ++ .github/workflows/publish.yml | 3 + .gitignore | 141 +++++++++++++++++++++++++++- 4 files changed, 154 insertions(+), 1 deletion(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 46b1f9b..417c4a2 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -31,6 +31,9 @@ jobs: with: go-version: 1.16 + - name: Install Poetry + run: curl -sSL https://install.python-poetry.org | python3 - + - name: Install dependencies run: make setup diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index fb2ac01..12b262e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,4 +1,5 @@ name: Main + on: push: branches: @@ -7,6 +8,7 @@ on: - '**' - '!v[0-9]+.[0-9]+.[0-9]+' pull_request: + jobs: test_build: name: Test and build @@ -14,11 +16,17 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v2 + - name: Export GOBIN uses: actions/setup-go@v2 with: go-version: 1.16 + + - name: Install Poetry + run: curl -sSL https://install.python-poetry.org | python3 - + - name: Install dependencies run: make setup + - name: Run tests run: make test diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b6f8792..8fe045a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -25,6 +25,9 @@ jobs: with: go-version: 1.16 + - name: Install Poetry + run: curl -sSL https://install.python-poetry.org | python3 - + - name: Install dependencies run: make setup diff --git a/.gitignore b/.gitignore index 63ad616..5bb963f 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,143 @@ config.yml # Build documentation -docs/ \ No newline at end of file +docs/### Python +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + From 20de51591bceb02898a775d1c6ee51fd4082827d Mon Sep 17 00:00:00 2001 From: eikendev Date: Sun, 13 Feb 2022 16:20:27 +0100 Subject: [PATCH 04/17] Load virtual environment before running Semgrep --- .github/workflows/main.yml | 4 +++- .github/workflows/publish.yml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 12b262e..167b31b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -29,4 +29,6 @@ jobs: run: make setup - name: Run tests - run: make test + run: | + source $(poetry env info --path)/bin/activate + make test diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8fe045a..444e5bc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -32,7 +32,9 @@ jobs: run: make setup - name: Run tests - run: make test + run: | + source $(poetry env info --path)/bin/activate + make test - name: Log in to the Container registry uses: docker/login-action@v1 From 44e036d6115c1a4339125c56bfd0af5d51976c85 Mon Sep 17 00:00:00 2001 From: eikendev Date: Sun, 13 Feb 2022 16:24:48 +0100 Subject: [PATCH 05/17] Explicitly disable metrics for Semgrep --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 95fb3a3..11442ce 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ test: staticcheck ./... go test -v -cover ./... gosec -exclude-dir=tests ./... - semgrep --lang=go --config=tests/semgrep + semgrep --lang=go --config=tests/semgrep --metrics=off @printf '\n%s\n' "> Test successful" .PHONY: setup From e676b723e9d76ff707c8d636aab9b744653c0276 Mon Sep 17 00:00:00 2001 From: eikendev Date: Sun, 13 Feb 2022 16:57:07 +0100 Subject: [PATCH 06/17] Sanitize notification before processing it --- internal/api/notification.go | 18 ++++++------------ internal/model/notification.go | 12 ++++++++++++ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/internal/api/notification.go b/internal/api/notification.go index c04df4d..4198880 100644 --- a/internal/api/notification.go +++ b/internal/api/notification.go @@ -4,7 +4,6 @@ import ( "log" "net/http" "net/url" - "strings" "time" "github.com/pushbits/server/internal/authentication" @@ -45,23 +44,17 @@ type NotificationHandler struct { // @Failure 500,404,403 "" // @Router /message [post] func (h *NotificationHandler) CreateNotification(ctx *gin.Context) { - var notification model.Notification + application := authentication.GetApplication(ctx) + log.Printf("Sending notification for application %s.", application.Name) + var notification model.Notification if err := ctx.Bind(¬ification); err != nil { return } - application := authentication.GetApplication(ctx) - log.Printf("Sending notification for application %s.", application.Name) - - notification.ApplicationID = application.ID - if strings.TrimSpace(notification.Title) == "" { - notification.Title = application.Name - } - notification.Date = time.Now() + notification.Sanitize(application) messageID, err := h.DP.SendNotification(application, ¬ification) - if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success { return } @@ -86,8 +79,9 @@ func (h *NotificationHandler) CreateNotification(ctx *gin.Context) { // @Router /message/{message_id} [DELETE] func (h *NotificationHandler) DeleteNotification(ctx *gin.Context) { application := authentication.GetApplication(ctx) - id, err := getMessageID(ctx) + log.Printf("Deleting notification for application %s.", application.Name) + id, err := getMessageID(ctx) if success := successOrAbort(ctx, http.StatusUnprocessableEntity, err); !success { return } diff --git a/internal/model/notification.go b/internal/model/notification.go index 6239236..3fbb44f 100644 --- a/internal/model/notification.go +++ b/internal/model/notification.go @@ -1,6 +1,7 @@ package model import ( + "strings" "time" ) @@ -16,6 +17,17 @@ type Notification struct { Date time.Time `json:"date"` } +// Sanitize sets explicit defaults for a notification. +func (n *Notification) Sanitize(application *Application) { + n.ID = "" + n.UrlEncodedID = "" + n.ApplicationID = application.ID + if strings.TrimSpace(n.Title) == "" { + n.Title = application.Name + } + n.Date = time.Now() +} + // DeleteNotification holds information like the message ID of a deletion notification. type DeleteNotification struct { ID string `json:"id" form:"id"` From 42a4cca0edb16c4cb54d0166eca1598677cfdf8b Mon Sep 17 00:00:00 2001 From: eikendev Date: Sun, 13 Feb 2022 17:32:08 +0100 Subject: [PATCH 07/17] Fix .gitignore file --- .gitignore | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 5bb963f..e8efc28 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ out/ *.db config.yml +docs/ ### Go # Binaries for programs and plugins @@ -19,11 +20,7 @@ config.yml # Dependency directories (remove the comment below to include it) # vendor/ -*.code-workspace - -# Build documentation - -docs/### Python +### Python # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] @@ -163,3 +160,14 @@ dmypy.json # Cython debug symbols cython_debug/ +### VisualStudioCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + From 9dcb8242b893c4c7c78733e87aee07a81ac42107 Mon Sep 17 00:00:00 2001 From: eikendev Date: Sun, 13 Feb 2022 18:40:56 +0100 Subject: [PATCH 08/17] Update README.md file --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 68af19d..1800911 100644 --- a/README.md +++ b/README.md @@ -57,10 +57,12 @@ Still, if you haven't tried it yet, we'd encourage you to check it out. - [ ] Two-factor authentication, [issue](https://github.com/pushbits/server/issues/19) - [ ] Bi-directional key verification, [issue](https://github.com/pushbits/server/issues/20) -## 👮 Acknowledgments +## 👮 License and Acknowledgments -The idea for this software and most parts of the initial source are heavily inspired by [Gotify](https://gotify.net/). -Many thanks to [jmattheis](https://jmattheis.de/) for his well-structured code. +Please refer to [the LICENSE file](LICENSE) to learn more about the license of this code. +It applies only where not specified differently. + +The idea for this software was inspired by [Gotify](https://gotify.net/). ## 💻 Development From a75478f83b81f7399559d4f0bf5d4d806eb6c3ad Mon Sep 17 00:00:00 2001 From: eikendev Date: Sun, 13 Feb 2022 18:42:32 +0100 Subject: [PATCH 09/17] Update README.md file --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1800911..e08a4c6 100644 --- a/README.md +++ b/README.md @@ -73,4 +73,4 @@ You can retrieve it by checking out the repository as follows. git clone https://github.com/pushbits/server.git ``` -[![Stargazers over time](https://starchart.cc/pushbits/server.svg)](https://starchart.cc/pushbits/server) +Check out [the stargazers over time](https://starchart.cc/pushbits/server) for a fancy graph. From 5267359a6064c46d4df67567eba75c870741a6d2 Mon Sep 17 00:00:00 2001 From: eikendev Date: Sun, 13 Feb 2022 21:00:06 +0100 Subject: [PATCH 10/17] Add semgrep-rules as submodule --- .gitmodules | 3 + Makefile | 22 ++- internal/authentication/credentials/hibp.go | 2 +- internal/database/database.go | 2 +- tests/semgrep-rules | 1 + .../go/aws-lambda/security/database-sqli.yaml | 51 ------ ...dler-assignment-from-multiple-sources.yaml | 57 ------- .../session-cookie-missing-httponly.yaml | 33 ---- .../audit/session-cookie-missing-secure.yaml | 32 ---- .../grpc-client-insecure-connection.yaml | 26 --- .../grpc-server-insecure-connection.yaml | 41 ----- .../security/audit/jwt-parse-unverified.yaml | 22 --- .../go/jwt-go/security/jwt-none-alg.yaml | 26 --- tests/semgrep/go/jwt-go/security/jwt.yaml | 19 --- .../channel-guarded-with-mutex.yaml | 22 --- .../lang/best-practice/hidden-goroutine.yaml | 27 --- .../go/lang/correctness/looppointer.yaml | 29 ---- .../lang/correctness/overflow/overflow.yaml | 39 ----- .../permissions/file_permission.yaml | 25 --- .../lang/correctness/use-filepath-join.yaml | 16 -- .../go/lang/correctness/useless-eqeq.yaml | 31 ---- .../lang/maintainability/useless-ifelse.yaml | 33 ---- .../security/audit/crypto/bad_imports.yaml | 48 ------ .../security/audit/crypto/insecure_ssh.yaml | 23 --- .../security/audit/crypto/math_random.yaml | 32 ---- .../audit/crypto/missing-ssl-minversion.yaml | 28 ---- .../go/lang/security/audit/crypto/ssl.yaml | 23 --- .../go/lang/security/audit/crypto/tls.yaml | 45 ----- .../audit/crypto/use_of_weak_crypto.yaml | 73 --------- .../audit/crypto/use_of_weak_rsa_key.yaml | 24 --- .../audit/dangerous-command-write.yaml | 35 ---- .../security/audit/dangerous-exec-cmd.yaml | 76 --------- .../audit/dangerous-exec-command.yaml | 47 ------ .../audit/dangerous-syscall-exec.yaml | 88 ---------- .../database/string-formatted-query.yaml | 155 ------------------ .../security/audit/md5-used-as-password.yaml | 35 ---- .../go/lang/security/audit/net/bind_all.yaml | 21 --- .../audit/net/cookie-missing-httponly.yaml | 34 ---- .../audit/net/cookie-missing-secure.yaml | 33 ---- .../net/dynamic-httptrace-clienttrace.yaml | 32 ---- .../audit/net/formatted-template-string.yaml | 47 ------ .../go/lang/security/audit/net/pprof.yaml | 35 ---- .../audit/net/unescaped-data-in-htmlattr.yaml | 47 ------ .../audit/net/unescaped-data-in-js.yaml | 46 ------ .../audit/net/unescaped-data-in-url.yaml | 48 ------ .../go/lang/security/audit/net/use-tls.yaml | 18 -- ...p-xss-using-responsewriter-and-printf.yaml | 61 ------- .../lang/security/audit/reflect-makefunc.yaml | 18 -- .../lang/security/audit/sqli/gosql-sqli.yaml | 52 ------ .../lang/security/audit/sqli/pg-orm-sqli.yaml | 55 ------- .../go/lang/security/audit/sqli/pg-sqli.yaml | 55 ------- .../go/lang/security/audit/sqli/pgx-sqli.yaml | 59 ------- .../audit/unsafe-reflect-by-name.yaml | 34 ---- .../go/lang/security/audit/unsafe.yaml | 17 -- .../audit/xss/import-text-template.yaml | 21 --- .../no-direct-write-to-responsewriter.yaml | 40 ----- .../xss/no-fprintf-to-responsewriter.yaml | 33 ---- .../audit/xss/no-interpolation-in-tag.yaml | 24 --- .../no-interpolation-js-template-string.yaml | 28 ---- .../no-io-writestring-to-responsewriter.yaml | 34 ---- .../xss/no-printf-in-responsewriter.yaml | 33 ---- .../xss/template-html-does-not-escape.yaml | 34 ---- tests/semgrep/go/lang/security/bad_tmp.yaml | 15 -- .../go/lang/security/decompression_bomb.yaml | 59 ------- .../lang/security/filepath-clean-misuse.yaml | 41 ----- .../security/injection/raw-html-format.yaml | 47 ------ .../injection/tainted-sql-string.yaml | 50 ------ .../security/injection/tainted-url-host.yaml | 46 ------ tests/semgrep/go/lang/security/zip.yaml | 20 --- .../security/audit/dangerous-execution.yaml | 24 --- .../go/template/security/insecure-types.yaml | 26 --- 71 files changed, 23 insertions(+), 2555 deletions(-) create mode 100644 .gitmodules create mode 160000 tests/semgrep-rules delete mode 100644 tests/semgrep/go/aws-lambda/security/database-sqli.yaml delete mode 100644 tests/semgrep/go/gorilla/security/audit/handler-assignment-from-multiple-sources.yaml delete mode 100644 tests/semgrep/go/gorilla/security/audit/session-cookie-missing-httponly.yaml delete mode 100644 tests/semgrep/go/gorilla/security/audit/session-cookie-missing-secure.yaml delete mode 100644 tests/semgrep/go/grpc/security/grpc-client-insecure-connection.yaml delete mode 100644 tests/semgrep/go/grpc/security/grpc-server-insecure-connection.yaml delete mode 100644 tests/semgrep/go/jwt-go/security/audit/jwt-parse-unverified.yaml delete mode 100644 tests/semgrep/go/jwt-go/security/jwt-none-alg.yaml delete mode 100644 tests/semgrep/go/jwt-go/security/jwt.yaml delete mode 100644 tests/semgrep/go/lang/best-practice/channel-guarded-with-mutex.yaml delete mode 100644 tests/semgrep/go/lang/best-practice/hidden-goroutine.yaml delete mode 100644 tests/semgrep/go/lang/correctness/looppointer.yaml delete mode 100644 tests/semgrep/go/lang/correctness/overflow/overflow.yaml delete mode 100644 tests/semgrep/go/lang/correctness/permissions/file_permission.yaml delete mode 100644 tests/semgrep/go/lang/correctness/use-filepath-join.yaml delete mode 100644 tests/semgrep/go/lang/correctness/useless-eqeq.yaml delete mode 100644 tests/semgrep/go/lang/maintainability/useless-ifelse.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/crypto/bad_imports.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/crypto/insecure_ssh.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/crypto/math_random.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/crypto/missing-ssl-minversion.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/crypto/ssl.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/crypto/tls.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/crypto/use_of_weak_crypto.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/crypto/use_of_weak_rsa_key.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/dangerous-command-write.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/dangerous-exec-cmd.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/dangerous-exec-command.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/dangerous-syscall-exec.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/database/string-formatted-query.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/md5-used-as-password.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/net/bind_all.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/net/cookie-missing-httponly.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/net/cookie-missing-secure.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/net/dynamic-httptrace-clienttrace.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/net/formatted-template-string.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/net/pprof.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/net/unescaped-data-in-htmlattr.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/net/unescaped-data-in-js.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/net/unescaped-data-in-url.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/net/use-tls.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/net/wip-xss-using-responsewriter-and-printf.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/reflect-makefunc.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/sqli/gosql-sqli.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/sqli/pg-orm-sqli.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/sqli/pg-sqli.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/sqli/pgx-sqli.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/unsafe-reflect-by-name.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/unsafe.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/xss/import-text-template.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/xss/no-direct-write-to-responsewriter.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/xss/no-fprintf-to-responsewriter.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/xss/no-interpolation-in-tag.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/xss/no-interpolation-js-template-string.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/xss/no-io-writestring-to-responsewriter.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/xss/no-printf-in-responsewriter.yaml delete mode 100644 tests/semgrep/go/lang/security/audit/xss/template-html-does-not-escape.yaml delete mode 100644 tests/semgrep/go/lang/security/bad_tmp.yaml delete mode 100644 tests/semgrep/go/lang/security/decompression_bomb.yaml delete mode 100644 tests/semgrep/go/lang/security/filepath-clean-misuse.yaml delete mode 100644 tests/semgrep/go/lang/security/injection/raw-html-format.yaml delete mode 100644 tests/semgrep/go/lang/security/injection/tainted-sql-string.yaml delete mode 100644 tests/semgrep/go/lang/security/injection/tainted-url-host.yaml delete mode 100644 tests/semgrep/go/lang/security/zip.yaml delete mode 100644 tests/semgrep/go/otto/security/audit/dangerous-execution.yaml delete mode 100644 tests/semgrep/go/template/security/insecure-types.yaml diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..7245332 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "tests/semgrep-rules"] + path = tests/semgrep-rules + url = https://github.com/returntocorp/semgrep-rules diff --git a/Makefile b/Makefile index 11442ce..fbecf5d 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,33 @@ +OUTDIR := ./out + +SEMGREP_MODFILE := ./tests/semgrep-rules/go.mod + .PHONY: build build: - mkdir -p ./out - go build -ldflags="-w -s" -o ./out/pushbits ./cmd/pushbits + mkdir -p $(OUTDIR) + go build -ldflags="-w -s" -o $(OUTDIR)/pushbits ./cmd/pushbits + +.PHONY: clean +clean: + rm -rf $(OUTDIR) + rm -rf $(SEMGREP_MODFILE) .PHONY: test test: - stdout=$$(gofmt -l . 2>&1); if [ "$$stdout" ]; then exit 1; fi + touch $(SEMGREP_MODFILE) # Needed so the Go files of semgrep-rules do not interfere with static analysis + go fmt ./... go vet ./... - gocyclo -over 10 $(shell find . -iname '*.go' -type f) + gocyclo -over 10 $(shell find . -type f \( -iname '*.go' ! -path "./tests/semgrep-rules/*" \)) staticcheck ./... go test -v -cover ./... gosec -exclude-dir=tests ./... - semgrep --lang=go --config=tests/semgrep --metrics=off + semgrep --lang=go --config=tests/semgrep-rules/go --metrics=off + rm -rf $(SEMGREP_MODFILE) @printf '\n%s\n' "> Test successful" .PHONY: setup setup: + git submodule update --init --recursive go install github.com/fzipp/gocyclo/cmd/gocyclo@latest go install github.com/securego/gosec/v2/cmd/gosec@latest go install github.com/swaggo/swag/cmd/swag@latest diff --git a/internal/authentication/credentials/hibp.go b/internal/authentication/credentials/hibp.go index d10f3f2..8522497 100644 --- a/internal/authentication/credentials/hibp.go +++ b/internal/authentication/credentials/hibp.go @@ -21,7 +21,7 @@ func IsPasswordPwned(password string) (bool, error) { return true, nil } - // nosemgrep: tests.semgrep.go.lang.security.audit.crypto.insecure-module-used, tests.semgrep.go.lang.security.audit.crypto.use-of-sha1 + // nosemgrep: tests.semgrep-rules.go.lang.security.audit.crypto.insecure-module-used, tests.semgrep-rules.go.lang.security.audit.crypto.use-of-sha1 hash := sha1.Sum([]byte(password)) //#nosec G401 -- False positive, only the first 5 bytes are transmitted. hashStr := fmt.Sprintf("%X", hash) lookup := hashStr[0:5] diff --git a/internal/database/database.go b/internal/database/database.go index affe7fd..6ea7b81 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -27,7 +27,7 @@ func createFileDir(file string) { dir := filepath.Dir(file) if _, err := os.Stat(dir); os.IsNotExist(err) { - // nosemgrep: tests.semgrep.go.lang.correctness.permissions.incorrect-default-permission + // nosemgrep: tests.semgrep-rules.go.lang.correctness.permissions.incorrect-default-permission if err := os.MkdirAll(dir, 0750); err != nil { panic(err) } diff --git a/tests/semgrep-rules b/tests/semgrep-rules new file mode 160000 index 0000000..46e040f --- /dev/null +++ b/tests/semgrep-rules @@ -0,0 +1 @@ +Subproject commit 46e040f844c2b1c40599c8d4f1cdf277b197329e diff --git a/tests/semgrep/go/aws-lambda/security/database-sqli.yaml b/tests/semgrep/go/aws-lambda/security/database-sqli.yaml deleted file mode 100644 index f4c3bba..0000000 --- a/tests/semgrep/go/aws-lambda/security/database-sqli.yaml +++ /dev/null @@ -1,51 +0,0 @@ -rules: -- id: database-sqli - languages: - - go - message: >- - Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if the variable is user-controlled - and not properly sanitized. In order to prevent SQL injection, - used parameterized queries or prepared statements instead. - You can use prepared statements with the 'Prepare' and 'PrepareContext' calls. - mode: taint - metadata: - references: - - 'https://pkg.go.dev/database/sql#DB.Query' - category: security - owasp: "A1: Injection" - cwe: "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')" - technology: - - aws-lambda - - database - - sql - pattern-sinks: - - patterns: - - pattern: $QUERY - - pattern-either: - - pattern: $DB.Exec($QUERY,...) - - pattern: $DB.ExecContent($QUERY,...) - - pattern: $DB.Query($QUERY,...) - - pattern: $DB.QueryContext($QUERY,...) - - pattern: $DB.QueryRow($QUERY,...) - - pattern: $DB.QueryRowContext($QUERY,...) - - pattern-inside: | - import "database/sql" - ... - pattern-sources: - - patterns: - - pattern-either: - - pattern-inside: | - func $HANDLER($CTX $CTXTYPE, $EVENT $TYPE, ...) {...} - ... - lambda.Start($HANDLER, ...) - - patterns: - - pattern-inside: | - func $HANDLER($EVENT $TYPE) {...} - ... - lambda.Start($HANDLER, ...) - - pattern-not-inside: | - func $HANDLER($EVENT context.Context) {...} - ... - lambda.Start($HANDLER, ...) - - pattern: $EVENT - severity: WARNING diff --git a/tests/semgrep/go/gorilla/security/audit/handler-assignment-from-multiple-sources.yaml b/tests/semgrep/go/gorilla/security/audit/handler-assignment-from-multiple-sources.yaml deleted file mode 100644 index 6663481..0000000 --- a/tests/semgrep/go/gorilla/security/audit/handler-assignment-from-multiple-sources.yaml +++ /dev/null @@ -1,57 +0,0 @@ -rules: - - id: handler-assignment-from-multiple-sources - metadata: - cwe: "CWE-289: Authentication Bypass by Alternate Name" - owasp: "A2: Broken Authentication" - owaspapi: "API1: Broken Object Level Authorization" - category: security - technology: - - gorilla - confidence: MEDIUM - patterns: - - pattern-inside: | - func $HANDLER(..., $R *http.Request, ...) { - ... - } - - pattern-not: | - $VAR = true - ... - $VAR = false - - pattern-not: | - $VAR = false - ... - $VAR = true - - pattern-not: | - $VAR = $X - ... - $VAR = $X - - pattern-not: | - $VAR = $X - ... - $VAR = $Z(..., $VAR, ...) - - pattern-not: | - $VAR = $X - ... - $VAR = $Z($W(..., $VAR, ...)) - - pattern-not: | - $VAR = $X - ... - $VAR = $VAR[:$Z(..., $VAR, ...)] - - pattern-not: | - $VAR = $X - ... - $VAR = $VAR[$Z(..., $VAR, ...):] - - pattern-not: | - $VAR = $X - ... - $VAR = $VAR[$Z(..., $VAR, ...)] - - pattern: | - $VAR = $X - ... - $VAR = $Y - message: - "Variable $VAR is assigned from two different sources: '$X' and '$Y'. Make\ - \ sure this is intended, as this could cause logic bugs if they are treated as\ - \ they are the same object." - languages: [go] - severity: WARNING diff --git a/tests/semgrep/go/gorilla/security/audit/session-cookie-missing-httponly.yaml b/tests/semgrep/go/gorilla/security/audit/session-cookie-missing-httponly.yaml deleted file mode 100644 index 1f64f96..0000000 --- a/tests/semgrep/go/gorilla/security/audit/session-cookie-missing-httponly.yaml +++ /dev/null @@ -1,33 +0,0 @@ -rules: - - id: session-cookie-missing-httponly - patterns: - - pattern-not-inside: | - &sessions.Options{ - ..., - HttpOnly: true, - ..., - } - - pattern: | - &sessions.Options{ - ..., - } - message: >- - A session cookie was detected without setting the 'HttpOnly' flag. - The 'HttpOnly' flag for cookies instructs the browser to forbid - client-side scripts from reading the cookie which mitigates XSS - attacks. Set the 'HttpOnly' flag by setting 'HttpOnly' to 'true' - in the Options struct. - metadata: - cwe: "CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag" - owasp: "A3: Sensitive Data Exposure" - references: - - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/user/session/session.go#L69 - category: security - technology: - - gorilla - confidence: MEDIUM - fix-regex: - regex: (HttpOnly\s*:\s+)false - replacement: \1true - severity: WARNING - languages: [go] diff --git a/tests/semgrep/go/gorilla/security/audit/session-cookie-missing-secure.yaml b/tests/semgrep/go/gorilla/security/audit/session-cookie-missing-secure.yaml deleted file mode 100644 index f22f5d8..0000000 --- a/tests/semgrep/go/gorilla/security/audit/session-cookie-missing-secure.yaml +++ /dev/null @@ -1,32 +0,0 @@ -rules: - - id: session-cookie-missing-secure - patterns: - - pattern-not-inside: | - &sessions.Options{ - ..., - Secure: true, - ..., - } - - pattern: | - &sessions.Options{ - ..., - } - message: >- - A session cookie was detected without setting the 'Secure' flag. - The 'secure' flag for cookies prevents the client from transmitting - the cookie over insecure channels such as HTTP. Set the 'Secure' - flag by setting 'Secure' to 'true' in the Options struct. - metadata: - cwe: "CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute" - owasp: "A3: Sensitive Data Exposure" - references: - - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/user/session/session.go#L69 - category: security - technology: - - gorilla - confidence: MEDIUM - fix-regex: - regex: (Secure\s*:\s+)false - replacement: \1true - severity: WARNING - languages: [go] diff --git a/tests/semgrep/go/grpc/security/grpc-client-insecure-connection.yaml b/tests/semgrep/go/grpc/security/grpc-client-insecure-connection.yaml deleted file mode 100644 index cc9b08f..0000000 --- a/tests/semgrep/go/grpc/security/grpc-client-insecure-connection.yaml +++ /dev/null @@ -1,26 +0,0 @@ -rules: - - id: grpc-client-insecure-connection - metadata: - cwe: "CWE-300: Channel Accessible by Non-Endpoint" - references: - - https://blog.gopheracademy.com/advent-2019/go-grps-and-tls/#connection-without-encryption - category: security - technology: - - grpc - confidence: HIGH - message: >- - Found an insecure gRPC connection using 'grpc.WithInsecure()'. This creates a - connection without encryption to a gRPC - server. A malicious attacker could tamper with the gRPC message, which could compromise - the machine. Instead, establish - a secure connection with an - SSL certificate using the 'grpc.WithTransportCredentials()' function. You can - create a create credentials using a 'tls.Config{}' - struct with 'credentials.NewTLS()'. The final fix looks like this: 'grpc.WithTransportCredentials(credentials.NewTLS())'. - languages: - - go - severity: ERROR - pattern: $GRPC.Dial($ADDR, ..., $GRPC.WithInsecure(...), ...) - fix-regex: - regex: (.*)WithInsecure\(.*?\) - replacement: \1WithTransportCredentials(credentials.NewTLS()) diff --git a/tests/semgrep/go/grpc/security/grpc-server-insecure-connection.yaml b/tests/semgrep/go/grpc/security/grpc-server-insecure-connection.yaml deleted file mode 100644 index 3168df9..0000000 --- a/tests/semgrep/go/grpc/security/grpc-server-insecure-connection.yaml +++ /dev/null @@ -1,41 +0,0 @@ -rules: - - id: grpc-server-insecure-connection - metadata: - cwe: "CWE-300: Channel Accessible by Non-Endpoint" - references: - - https://blog.gopheracademy.com/advent-2019/go-grps-and-tls/#connection-without-encryption - category: security - technology: - - grpc - confidence: HIGH - message: >- - Found an insecure gRPC server without 'grpc.Creds()' or options with credentials. - This allows for a connection without - encryption to this server. - A malicious attacker could tamper with the gRPC message, which could compromise - the machine. Include credentials derived - from an SSL certificate in order to create a secure gRPC connection. You can create - credentials using 'credentials.NewServerTLSFromFile("cert.pem", - "cert.key")'. - languages: - - go - severity: ERROR - patterns: - - pattern-not: grpc.NewServer(..., grpc.Creds(...), ...) - - pattern-not-inside: | - $OPTS := []grpc.ServerOption{ - ..., - grpc.Creds(credentials.NewClientTLSFromCert(...)), - ..., - } - grpc.NewServer($OPTS...) - - pattern-not-inside: | - $CREDS := credentials.NewClientTLSFromCert(...) - ... - $OPTS := []grpc.ServerOption{ - ..., - $CREDS, - ..., - } - grpc.NewServer($OPTS...) - - pattern: grpc.NewServer(...) diff --git a/tests/semgrep/go/jwt-go/security/audit/jwt-parse-unverified.yaml b/tests/semgrep/go/jwt-go/security/audit/jwt-parse-unverified.yaml deleted file mode 100644 index 103575c..0000000 --- a/tests/semgrep/go/jwt-go/security/audit/jwt-parse-unverified.yaml +++ /dev/null @@ -1,22 +0,0 @@ -rules: - - id: jwt-go-parse-unverified - message: >- - Detected the decoding of a JWT token without a verify step. - Don't use `ParseUnverified` unless you know what you're doing - This method parses the token but doesn't validate the signature. It's only ever useful in cases where you know the signature is valid (because it has been checked previously in the stack) and you want to extract values from it. - metadata: - cwe: "CWE-345: Insufficient Verification of Data Authenticity" - owasp: "A2: Broken Authentication" - source-rule-url: https://r2c.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - category: security - technology: - - jwt - confidence: MEDIUM - languages: [go] - severity: WARNING - patterns: - - pattern-inside: | - import "github.com/dgrijalva/jwt-go" - ... - - pattern: | - $JWT.ParseUnverified(...) diff --git a/tests/semgrep/go/jwt-go/security/jwt-none-alg.yaml b/tests/semgrep/go/jwt-go/security/jwt-none-alg.yaml deleted file mode 100644 index 2c83506..0000000 --- a/tests/semgrep/go/jwt-go/security/jwt-none-alg.yaml +++ /dev/null @@ -1,26 +0,0 @@ -rules: - - id: jwt-go-none-algorithm - message: >- - Detected use of the 'none' algorithm in a JWT token. - The 'none' algorithm assumes the integrity of the token has already - been verified. This would allow a malicious actor to forge a JWT token - that will automatically be verified. Do not explicitly use the 'none' - algorithm. Instead, use an algorithm such as 'HS256'. - metadata: - cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" - owasp: "A2: Broken Authentication" - source-rule-url: https://r2c.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/ - category: security - technology: - - jwt - confidence: HIGH - languages: [go] - severity: ERROR - patterns: - - pattern-inside: | - import "github.com/dgrijalva/jwt-go" - ... - - pattern-either: - - pattern: | - jwt.SigningMethodNone - - pattern: jwt.UnsafeAllowNoneSignatureType diff --git a/tests/semgrep/go/jwt-go/security/jwt.yaml b/tests/semgrep/go/jwt-go/security/jwt.yaml deleted file mode 100644 index de76549..0000000 --- a/tests/semgrep/go/jwt-go/security/jwt.yaml +++ /dev/null @@ -1,19 +0,0 @@ -rules: - - id: hardcoded-jwt-key - metadata: - cwe: "CWE-798: Use of Hard-coded Credentials" - owasp: "A2: Broken Authentication" - category: security - technology: - - jwt - confidence: MEDIUM - pattern-either: - - pattern: | - $X = []byte("...") - ... - $Y := $TOKEN.SignedString($X) - - pattern: | - $TOKEN.SignedString([]byte("...")) - message: JWT token is hardcoded - languages: [go] - severity: WARNING diff --git a/tests/semgrep/go/lang/best-practice/channel-guarded-with-mutex.yaml b/tests/semgrep/go/lang/best-practice/channel-guarded-with-mutex.yaml deleted file mode 100644 index ab61095..0000000 --- a/tests/semgrep/go/lang/best-practice/channel-guarded-with-mutex.yaml +++ /dev/null @@ -1,22 +0,0 @@ -rules: - - id: channel-guarded-with-mutex - pattern-either: - - pattern: | - $MUX.Lock() - $VALUE <- $CHANNEL - $MUX.Unlock() - - pattern: | - $MUX.Lock() - $VALUE = <- $CHANNEL - $MUX.Unlock() - message: >- - Detected a channel guarded with a mutex. Channels already have - an internal mutex, so this is unnecessary. Remove the mutex. - See https://hackmongo.com/page/golang-antipatterns/#guarded-channel - for more information. - languages: [go] - severity: WARNING - metadata: - category: best-practice - technology: - - go diff --git a/tests/semgrep/go/lang/best-practice/hidden-goroutine.yaml b/tests/semgrep/go/lang/best-practice/hidden-goroutine.yaml deleted file mode 100644 index 16425cc..0000000 --- a/tests/semgrep/go/lang/best-practice/hidden-goroutine.yaml +++ /dev/null @@ -1,27 +0,0 @@ -rules: - - id: hidden-goroutine - patterns: - - pattern-not: | - func $FUNC(...) { - go func() { - ... - }(...) - $MORE - } - - pattern: | - func $FUNC(...) { - go func() { - ... - }(...) - } - message: >- - Detected a hidden goroutine. Function invocations are expected to synchronous, - and this function will execute asynchronously because all it does is call a - goroutine. Instead, remove the internal goroutine and call the function using - 'go'. - languages: [go] - severity: WARNING - metadata: - category: best-practice - technology: - - go diff --git a/tests/semgrep/go/lang/correctness/looppointer.yaml b/tests/semgrep/go/lang/correctness/looppointer.yaml deleted file mode 100644 index 43f8113..0000000 --- a/tests/semgrep/go/lang/correctness/looppointer.yaml +++ /dev/null @@ -1,29 +0,0 @@ -rules: - - id: exported_loop_pointer - message: >- - `$VALUE` is a loop pointer that may be exported from the loop. This pointer is - shared between loop iterations, so the exported reference will always point to - the last loop value, which is likely unintentional. To fix, copy the pointer to - a new pointer within the loop. - metadata: - references: - - https://github.com/kyoh86/looppointer - category: correctness - technology: - - go - severity: WARNING - languages: - - go - pattern-either: - - pattern: | - for _, $VALUE := range $SOURCE { - <... &($VALUE) ...> - } - - pattern: | - for _, $VALUE := range $SOURCE { - <... func() { <... &$VALUE ...> } ...> - } - - pattern: | - for _, $VALUE := range $SOURCE { - <... $ANYTHING(..., <... $VALUE ...>, ...) ...> - } diff --git a/tests/semgrep/go/lang/correctness/overflow/overflow.yaml b/tests/semgrep/go/lang/correctness/overflow/overflow.yaml deleted file mode 100644 index 09c753f..0000000 --- a/tests/semgrep/go/lang/correctness/overflow/overflow.yaml +++ /dev/null @@ -1,39 +0,0 @@ -rules: - - id: integer-overflow-int16 - message: - Detected conversion of the result of a strconv.Atoi command to an int16. This could lead to an integer overflow, - which could possibly result in unexpected behavior and even privilege escalation. Instead, use `strconv.ParseInt`. - languages: [go] - severity: WARNING - patterns: - - pattern: | - $F, $ERR := strconv.Atoi($NUM) - ... - int16($F) - - metavariable-comparison: - metavariable: $NUM - comparison: $NUM > 32767 or $NUM < -32768 - strip: true - metadata: - category: correctness - technology: - - go - - id: integer-overflow-int32 - message: - Detected conversion of the result of a strconv.Atoi command to an int32. This could lead to an integer overflow, - which could possibly result in unexpected behavior and even privilege escalation. Instead, use `strconv.ParseInt`. - languages: [go] - severity: WARNING - patterns: - - pattern: | - $F, $ERR := strconv.Atoi($NUM) - ... - int32($F) - - metavariable-comparison: - metavariable: $NUM - comparison: $NUM > 2147483647 or $NUM < -2147483648 - strip: true - metadata: - category: correctness - technology: - - go diff --git a/tests/semgrep/go/lang/correctness/permissions/file_permission.yaml b/tests/semgrep/go/lang/correctness/permissions/file_permission.yaml deleted file mode 100644 index 9a316ea..0000000 --- a/tests/semgrep/go/lang/correctness/permissions/file_permission.yaml +++ /dev/null @@ -1,25 +0,0 @@ -rules: - - id: incorrect-default-permission - message: - Detected file permissions that are set to more than `0600` (user/owner can read and write). Setting file permissions - to higher than `0600` is most likely unnecessary and violates the principle of least privilege. Instead, set permissions - to be `0600` or less for os.Chmod, os.Mkdir, os.OpenFile, os.MkdirAll, and ioutil.WriteFile - metadata: - cwe: "CWE-276: Incorrect Default Permissions" - source_rule_url: https://github.com/securego/gosec - category: correctness - technology: - - go - severity: WARNING - languages: [go] - patterns: - - pattern-either: - - pattern: os.Chmod($NAME, $PERM) - - pattern: os.Mkdir($NAME, $PERM) - - pattern: os.OpenFile($NAME, $FLAG, $PERM) - - pattern: os.MkdirAll($NAME, $PERM) - - pattern: ioutil.WriteFile($NAME, $DATA, $PERM) - - metavariable-comparison: - metavariable: $PERM - comparison: $PERM > 0o600 - base: 8 diff --git a/tests/semgrep/go/lang/correctness/use-filepath-join.yaml b/tests/semgrep/go/lang/correctness/use-filepath-join.yaml deleted file mode 100644 index 2c6b1ad..0000000 --- a/tests/semgrep/go/lang/correctness/use-filepath-join.yaml +++ /dev/null @@ -1,16 +0,0 @@ -rules: -- id: use-filepath-join - languages: [go] - severity: WARNING - message: >- - `path.Join(...)` always joins using a forward slash. This may cause - issues on Windows or other systems using a different delimiter. Use - `filepath.Join(...)` instead which uses OS-specific path separators. - pattern: path.Join(...) - metadata: - category: correctness - references: - - https://parsiya.net/blog/2019-03-09-path.join-considered-harmful/ - - https://go.dev/src/path/path.go?s=4034:4066#L145 - technology: - - go diff --git a/tests/semgrep/go/lang/correctness/useless-eqeq.yaml b/tests/semgrep/go/lang/correctness/useless-eqeq.yaml deleted file mode 100644 index 5febc58..0000000 --- a/tests/semgrep/go/lang/correctness/useless-eqeq.yaml +++ /dev/null @@ -1,31 +0,0 @@ -rules: - - id: eqeq-is-bad - patterns: - - pattern-not-inside: assert(...) - - pattern-either: - - pattern: $X == $X - - pattern: $X != $X - - pattern-not: 1 == 1 - message: - Detected useless comparison operation `$X == $X` or `$X != $X`. This will always return 'True' or 'False' and therefore - is not necessary. Instead, remove this comparison operation or use another comparison expression that is not deterministic. - languages: [go] - severity: ERROR - metadata: - category: correctness - technology: - - go - - id: hardcoded-eq-true-or-false - message: - Detected useless if statement. 'if (True)' and 'if (False)' always result in the same behavior, and therefore is - not necessary in the code. Remove the 'if (False)' expression completely or just the 'if (True)' comparison depending - on which expression is in the code. - languages: [go] - severity: ERROR - pattern-either: - - pattern: if (true) { ... } - - pattern: if (false) { ... } - metadata: - category: correctness - technology: - - go diff --git a/tests/semgrep/go/lang/maintainability/useless-ifelse.yaml b/tests/semgrep/go/lang/maintainability/useless-ifelse.yaml deleted file mode 100644 index f5b9b4b..0000000 --- a/tests/semgrep/go/lang/maintainability/useless-ifelse.yaml +++ /dev/null @@ -1,33 +0,0 @@ -rules: - - id: useless-if-conditional - message: - Detected an if block that checks for the same condition on both branches (`$X`). The second condition check is - useless as it is the same as the first, and therefore can be removed from the code, - languages: [go] - severity: WARNING - pattern: | - if ($X) { - ... - } else if ($X) { - ... - } - metadata: - category: maintainability - technology: - - go - - id: useless-if-body - pattern: | - if ($X) { - $S - } else { - $S - } - message: - Detected identical statements in the if body and the else body of an if-statement. This will lead to the same code - being executed no matter what the if-expression evaluates to. Instead, remove the if statement. - languages: [go] - severity: WARNING - metadata: - category: maintainability - technology: - - go diff --git a/tests/semgrep/go/lang/security/audit/crypto/bad_imports.yaml b/tests/semgrep/go/lang/security/audit/crypto/bad_imports.yaml deleted file mode 100644 index 2d9870b..0000000 --- a/tests/semgrep/go/lang/security/audit/crypto/bad_imports.yaml +++ /dev/null @@ -1,48 +0,0 @@ -rules: - - id: insecure-module-used - message: >- - Detected use of an insecure cryptographic hashing method. This method is known - to be broken and easily compromised. Use SHA256 or SHA3 instead. - metadata: - owasp: "A9: Using Components with Known Vulnerabilities" - cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" - source-rule-url: https://github.com/securego/gosec - references: - - https://godoc.org/golang.org/x/crypto/sha3 - category: security - technology: - - go - confidence: MEDIUM - languages: [go] - severity: WARNING - pattern-either: - - patterns: - - pattern-inside: | - import "crypto/md5" - ... - - pattern: | - md5.$FUNC(...) - - patterns: - - pattern-inside: | - import "crypto/des" - ... - - pattern: | - des.$FUNC(...) - - patterns: - - pattern-inside: | - import "crypto/sha1" - ... - - pattern: | - sha1.$FUNC(...) - - patterns: - - pattern-inside: | - import "crypto/rc4" - ... - - pattern: | - rc4.$FUNC(...) - - patterns: - - pattern-inside: | - import "net/http/cgi" - ... - - pattern: | - cgi.$FUNC(...) diff --git a/tests/semgrep/go/lang/security/audit/crypto/insecure_ssh.yaml b/tests/semgrep/go/lang/security/audit/crypto/insecure_ssh.yaml deleted file mode 100644 index dc706e6..0000000 --- a/tests/semgrep/go/lang/security/audit/crypto/insecure_ssh.yaml +++ /dev/null @@ -1,23 +0,0 @@ -rules: - - id: avoid-ssh-insecure-ignore-host-key - message: >- - Disabled host key verification detected. This allows man-in-the-middle - attacks. Use the 'golang.org/x/crypto/ssh/knownhosts' package to do - host key verification. - See https://skarlso.github.io/2019/02/17/go-ssh-with-host-key-verification/ - to learn more about the problem and how to fix it. - metadata: - cwe: "CWE-322: Key Exchange without Entity Authentication" - owasp: "A3: Sensitive Data Exposure" - source-rule-url: https://github.com/securego/gosec - references: - - https://skarlso.github.io/2019/02/17/go-ssh-with-host-key-verification/ - - https://gist.github.com/Skarlso/34321a230cf0245018288686c9e70b2d - category: security - technology: - - go - confidence: MEDIUM - languages: [go] - severity: WARNING - pattern: |- - ssh.InsecureIgnoreHostKey() diff --git a/tests/semgrep/go/lang/security/audit/crypto/math_random.yaml b/tests/semgrep/go/lang/security/audit/crypto/math_random.yaml deleted file mode 100644 index 3ca932d..0000000 --- a/tests/semgrep/go/lang/security/audit/crypto/math_random.yaml +++ /dev/null @@ -1,32 +0,0 @@ -rules: - - id: math-random-used - metadata: - cwe: "CWE-338: Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)" - owasp: "A3: Sensitive Data Exposure" - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#secure-random-number-generation - category: security - technology: - - go - confidence: MEDIUM - message: Do not use `math/rand`. Use `crypto/rand` instead. - languages: [go] - severity: WARNING - pattern-either: - - patterns: - - pattern-inside: | - import mrand "math/rand" - ... - - pattern-either: - - pattern: mrand.Int() - - pattern: mrand.Read(...) - - patterns: - - pattern-inside: | - import "math/rand" - ... - - pattern-not-inside: | - import "crypto/rand" - ... - - pattern-either: - - pattern: rand.Int() - - pattern: rand.Read(...) diff --git a/tests/semgrep/go/lang/security/audit/crypto/missing-ssl-minversion.yaml b/tests/semgrep/go/lang/security/audit/crypto/missing-ssl-minversion.yaml deleted file mode 100644 index 15ab7e0..0000000 --- a/tests/semgrep/go/lang/security/audit/crypto/missing-ssl-minversion.yaml +++ /dev/null @@ -1,28 +0,0 @@ -rules: - - id: missing-ssl-minversion - message: >- - `MinVersion` is missing from this TLS configuration. The default - value is TLS1.0 which is considered insecure. Explicitly set the - `MinVersion` to a secure version of TLS, such as `VersionTLS13`. - metadata: - cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" - owasp: "A9: Using Components with Known Vulnerabilities" - source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls_config.go - references: - - https://golang.org/doc/go1.14#crypto/tls - - https://golang.org/pkg/crypto/tls/#:~:text=MinVersion - - https://www.us-cert.gov/ncas/alerts/TA14-290A - category: security - technology: - - go - confidence: HIGH - languages: [go] - severity: WARNING - patterns: - - pattern: |- - tls.Config{...} - - pattern-not-inside: |- - tls.Config{..., MinVersion: ..., ...} - fix-regex: - regex: Config\s*\{ - replacement: "Config{MinVersion: SSL.VersionTLS13," diff --git a/tests/semgrep/go/lang/security/audit/crypto/ssl.yaml b/tests/semgrep/go/lang/security/audit/crypto/ssl.yaml deleted file mode 100644 index d01a478..0000000 --- a/tests/semgrep/go/lang/security/audit/crypto/ssl.yaml +++ /dev/null @@ -1,23 +0,0 @@ -rules: - - id: ssl-v3-is-insecure - message: >- - SSLv3 is insecure because it has known vulnerabilities. - Starting with go1.14, SSLv3 will be removed. Instead, use - 'tls.VersionTLS13'. - metadata: - cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" - owasp: "A9: Using Components with Known Vulnerabilities" - source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls_config.go - references: - - https://golang.org/doc/go1.14#crypto/tls - - https://www.us-cert.gov/ncas/alerts/TA14-290A - category: security - technology: - - go - confidence: HIGH - languages: [go] - severity: WARNING - fix-regex: - regex: VersionSSL30 - replacement: VersionTLS13 - pattern: "tls.Config{..., MinVersion: $TLS.VersionSSL30, ...}" diff --git a/tests/semgrep/go/lang/security/audit/crypto/tls.yaml b/tests/semgrep/go/lang/security/audit/crypto/tls.yaml deleted file mode 100644 index 7f19872..0000000 --- a/tests/semgrep/go/lang/security/audit/crypto/tls.yaml +++ /dev/null @@ -1,45 +0,0 @@ -rules: - - id: tls-with-insecure-cipher - message: >- - Detected an insecure CipherSuite via the 'tls' module. This suite is considered - weak. - Use the function 'tls.CipherSuites()' to get a list of good cipher suites. - See https://golang.org/pkg/crypto/tls/#InsecureCipherSuites - for why and what other cipher suites to use. - metadata: - cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" - owasp: "A9: Using Components with Known Vulnerabilities" - source-rule-url: https://github.com/securego/gosec/blob/master/rules/tls.go - references: - - https://golang.org/pkg/crypto/tls/#InsecureCipherSuites - category: security - technology: - - go - confidence: HIGH - languages: [go] - severity: WARNING - pattern-either: - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_RC4_128_SHA,...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_RSA_WITH_AES_128_CBC_SHA256,...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,...}} - - pattern: | - tls.Config{..., CipherSuites: []$TYPE{..., tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,...}} - - pattern: | - tls.CipherSuite{..., TLS_RSA_WITH_RC4_128_SHA ,...} - - pattern: | - tls.CipherSuite{..., TLS_RSA_WITH_AES_128_CBC_SHA256 ,...} - - pattern: | - tls.CipherSuite{..., TLS_ECDHE_ECDSA_WITH_RC4_128_SHA ,...} - - pattern: | - tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_RC4_128_SHA ,...} - - pattern: | - tls.CipherSuite{..., TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 ,...} - - pattern: |- - tls.CipherSuite{..., TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 ,...} diff --git a/tests/semgrep/go/lang/security/audit/crypto/use_of_weak_crypto.yaml b/tests/semgrep/go/lang/security/audit/crypto/use_of_weak_crypto.yaml deleted file mode 100644 index 1d80f52..0000000 --- a/tests/semgrep/go/lang/security/audit/crypto/use_of_weak_crypto.yaml +++ /dev/null @@ -1,73 +0,0 @@ -rules: - - id: use-of-md5 - message: >- - Detected MD5 hash algorithm which is considered insecure. MD5 is not - collision resistant and is therefore not suitable as a cryptographic - signature. Use SHA256 or SHA3 instead. - languages: [go] - severity: WARNING - metadata: - owasp: "A9: Using Components with Known Vulnerabilities" - cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" - source-rule-url: https://github.com/securego/gosec#available-rules - category: security - technology: - - go - confidence: MEDIUM - pattern-either: - - pattern: | - md5.New() - - pattern: | - md5.Sum(...) - - id: use-of-sha1 - message: >- - Detected SHA1 hash algorithm which is considered insecure. SHA1 is not - collision resistant and is therefore not suitable as a cryptographic - signature. Use SHA256 or SHA3 instead. - languages: [go] - severity: WARNING - metadata: - owasp: "A9: Using Components with Known Vulnerabilities" - cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" - source-rule-url: https://github.com/securego/gosec#available-rules - category: security - technology: - - go - pattern-either: - - pattern: | - sha1.New() - - pattern: | - sha1.Sum(...) - - id: use-of-DES - message: >- - Detected DES cipher algorithm which is insecure. The algorithm is - considered weak and has been deprecated. Use AES instead. - languages: [go] - severity: WARNING - metadata: - owasp: "A9: Using Components with Known Vulnerabilities" - cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" - source-rule-url: https://github.com/securego/gosec#available-rules - category: security - technology: - - go - pattern-either: - - pattern: | - des.NewTripleDESCipher(...) - - pattern: | - des.NewCipher(...) - - id: use-of-rc4 - message: >- - Detected RC4 cipher algorithm which is insecure. The algorithm has many - known vulnerabilities. Use AES instead. - languages: [go] - severity: WARNING - metadata: - owasp: "A9: Using Components with Known Vulnerabilities" - cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" - source-rule-url: https://github.com/securego/gosec#available-rules - category: security - technology: - - go - pattern: |- - rc4.NewCipher(...) diff --git a/tests/semgrep/go/lang/security/audit/crypto/use_of_weak_rsa_key.yaml b/tests/semgrep/go/lang/security/audit/crypto/use_of_weak_rsa_key.yaml deleted file mode 100644 index ac6e0bb..0000000 --- a/tests/semgrep/go/lang/security/audit/crypto/use_of_weak_rsa_key.yaml +++ /dev/null @@ -1,24 +0,0 @@ -rules: - - id: use-of-weak-rsa-key - message: RSA keys should be at least 2048 bits - languages: [go] - severity: WARNING - metadata: - cwe: "CWE-326: Inadequate Encryption Strength" - owasp: "A3: Sensitive Data Exposure" - source-rule-url: https://github.com/securego/gosec/blob/master/rules/rsa.go - references: - - https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#algorithms - category: security - technology: - - go - confidence: MEDIUM - patterns: - - pattern-either: - - pattern: | - rsa.GenerateKey(..., $BITS) - - pattern: | - rsa.GenerateMultiPrimeKey(..., $BITS) - - metavariable-comparison: - metavariable: $BITS - comparison: $BITS < 2048 diff --git a/tests/semgrep/go/lang/security/audit/dangerous-command-write.yaml b/tests/semgrep/go/lang/security/audit/dangerous-command-write.yaml deleted file mode 100644 index 872e7f6..0000000 --- a/tests/semgrep/go/lang/security/audit/dangerous-command-write.yaml +++ /dev/null @@ -1,35 +0,0 @@ -rules: - - id: dangerous-command-write - patterns: - - pattern: | - $CW.Write($BYTE) - - pattern-inside: | - $CW,$ERR := $CMD.StdinPipe() - ... - - pattern-not: | - $CW.Write("...") - - pattern-not: | - $CW.Write([]byte("...")) - - pattern-not: | - $CW.Write([]byte("..."+"...")) - - pattern-not-inside: | - $BYTE = []byte("..."); - ... - - pattern-not-inside: | - $BYTE = []byte("..."+"..."); - ... - - pattern-inside: | - import "os/exec" - ... - message: >- - Detected non-static command inside Write. Audit the input to '$CW.Write'. - If unverified user data can reach this call site, this is a code injection - vulnerability. A malicious actor can inject a malicious script to execute - arbitrary code. - severity: ERROR - languages: [go] - metadata: - category: security - technology: - - go - confidence: MEDIUM diff --git a/tests/semgrep/go/lang/security/audit/dangerous-exec-cmd.yaml b/tests/semgrep/go/lang/security/audit/dangerous-exec-cmd.yaml deleted file mode 100644 index 18d190c..0000000 --- a/tests/semgrep/go/lang/security/audit/dangerous-exec-cmd.yaml +++ /dev/null @@ -1,76 +0,0 @@ -rules: - - id: dangerous-exec-cmd - patterns: - - pattern-either: - - patterns: - - pattern: | - exec.Cmd {...,Path: $CMD,...} - - pattern-not: | - exec.Cmd {...,Path: "...",...} - - pattern-not-inside: | - $CMD,$ERR := exec.LookPath("..."); - ... - - pattern-not-inside: | - $CMD = "..."; - ... - - patterns: - - pattern: | - exec.Cmd {...,Args: $ARGS,...} - - pattern-not: | - exec.Cmd {...,Args: []string{...},...} - - pattern-not-inside: | - $ARGS = []string{"...",...}; - ... - - pattern-not-inside: | - $CMD = "..."; - ... - $ARGS = []string{$CMD,...}; - ... - - pattern-not-inside: | - $CMD = exec.LookPath("..."); - ... - $ARGS = []string{$CMD,...}; - ... - - patterns: - - pattern: | - exec.Cmd {...,Args: []string{$CMD,...},...} - - pattern-not: | - exec.Cmd {...,Args: []string{"...",...},...} - - pattern-not-inside: | - $CMD,$ERR := exec.LookPath("..."); - ... - - pattern-not-inside: | - $CMD = "..."; - ... - - patterns: - - pattern-either: - - pattern: | - exec.Cmd {...,Args: []string{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$EXE,...},...} - - patterns: - - pattern: | - exec.Cmd {...,Args: []string{$CMD,"-c",$EXE,...},...} - - pattern-inside: | - $CMD,$ERR := exec.LookPath("=~/(sh|bash|ksh|csh|tcsh|zsh)/"); - ... - - pattern-not: | - exec.Cmd {...,Args: []string{"...","...","...",...},...} - - pattern-not-inside: | - $EXE = "..."; - ... - - pattern-inside: | - import "os/exec" - ... - message: >- - Detected non-static command inside exec.Cmd. Audit the input to 'exec.Cmd'. - If unverified user data can reach this call site, this is a code injection - vulnerability. A malicious actor can inject a malicious script to execute - arbitrary code. - metadata: - cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')" - owasp: "A1: Injection" - category: security - technology: - - go - confidence: MEDIUM - severity: ERROR - languages: [go] diff --git a/tests/semgrep/go/lang/security/audit/dangerous-exec-command.yaml b/tests/semgrep/go/lang/security/audit/dangerous-exec-command.yaml deleted file mode 100644 index d445e03..0000000 --- a/tests/semgrep/go/lang/security/audit/dangerous-exec-command.yaml +++ /dev/null @@ -1,47 +0,0 @@ -rules: - - id: dangerous-exec-command - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: | - exec.Command($CMD,...) - - pattern: | - exec.CommandContext($CTX,$CMD,...) - - pattern-not: | - exec.Command("...",...) - - pattern-not: | - exec.CommandContext($CTX,"...",...) - - patterns: - - pattern-either: - - pattern: | - exec.Command("=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$CMD,...) - - pattern: | - exec.CommandContext($CTX,"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$CMD,...) - - pattern-not: | - exec.Command("...","...","...",...) - - pattern-not: | - exec.CommandContext($CTX,"...","...","...",...) - - pattern-inside: | - import "os/exec" - ... - - pattern-not-inside: | - $CMD,$ERR := exec.LookPath("..."); - ... - - pattern-not-inside: | - $CMD = "..."; - ... - message: >- - Detected non-static command inside Command. Audit the input to 'exec.Command'. - If unverified user data can reach this call site, this is a code injection - vulnerability. A malicious actor can inject a malicious script to execute - arbitrary code. - metadata: - cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')" - owasp: "A1: Injection" - category: security - technology: - - go - confidence: MEDIUM - severity: ERROR - languages: [go] diff --git a/tests/semgrep/go/lang/security/audit/dangerous-syscall-exec.yaml b/tests/semgrep/go/lang/security/audit/dangerous-syscall-exec.yaml deleted file mode 100644 index df96093..0000000 --- a/tests/semgrep/go/lang/security/audit/dangerous-syscall-exec.yaml +++ /dev/null @@ -1,88 +0,0 @@ -rules: - - id: dangerous-syscall-exec - patterns: - - pattern-either: - - patterns: - - pattern: | - syscall.$METHOD($BIN,...) - - pattern-not: | - syscall.$METHOD("...",...) - - pattern-not-inside: | - $BIN,$ERR := exec.LookPath("..."); - ... - - pattern-not-inside: | - $BIN = "..."; - ... - - patterns: - - pattern: | - syscall.$METHOD($BIN,$ARGS,...) - - pattern-not: | - syscall.$METHOD($BIN,[]string{"...",...},...) - - pattern-not-inside: | - $ARGS := []string{"...",...}; - ... - - pattern-not-inside: | - $CMD = "..."; - ... - $ARGS = []string{$CMD,...}; - ... - - pattern-not-inside: | - $CMD,$ERR := exec.LookPath("..."); - ... - $ARGS = []string{$CMD,...}; - ... - - patterns: - - pattern: | - syscall.$METHOD($BIN,[]string{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$EXE,...},...) - - pattern-not: | - syscall.$METHOD($BIN,[]string{"...","...","...",...},...) - - patterns: - - pattern: | - syscall.$METHOD($BIN,$ARGS,...) - - pattern-either: - - pattern-inside: | - $ARGS := []string{"=~/(sh|bash|ksh|csh|tcsh|zsh)/","-c",$EXE,...}; - ... - - pattern-inside: | - $CMD = "=~/(sh|bash|ksh|csh|tcsh|zsh)/"; - ... - $ARGS = []string{$CMD,"-c",$EXE,...}; - ... - - pattern-inside: | - $CMD,$ERR := exec.LookPath("=~/(sh|bash|ksh|csh|tcsh|zsh)/"); - ... - $ARGS = []string{$CMD,"-c",$EXE,...}; - ... - - pattern-not-inside: | - $ARGS := []string{"...","...","...",...}; - ... - - pattern-not-inside: | - $CMD = "..."; - ... - $ARGS = []string{$CMD,"...","...",...}; - ... - - pattern-not-inside: | - $CMD,$ERR := exec.LookPath("..."); - ... - $ARGS = []string{$CMD,"...","...",...}; - ... - - pattern-inside: | - import "syscall" - ... - - metavariable-regex: - metavariable: $METHOD - regex: (Exec|ForkExec) - message: >- - Detected non-static command inside Exec. Audit the input to 'syscall.Exec'. - If unverified user data can reach this call site, this is a code injection - vulnerability. A malicious actor can inject a malicious script to execute - arbitrary code. - metadata: - cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')" - owasp: "A1: Injection" - category: security - technology: - - go - confidence: MEDIUM - severity: ERROR - languages: [go] diff --git a/tests/semgrep/go/lang/security/audit/database/string-formatted-query.yaml b/tests/semgrep/go/lang/security/audit/database/string-formatted-query.yaml deleted file mode 100644 index ca7960c..0000000 --- a/tests/semgrep/go/lang/security/audit/database/string-formatted-query.yaml +++ /dev/null @@ -1,155 +0,0 @@ -rules: - - id: string-formatted-query - languages: [go] - message: >- - String-formatted SQL query detected. This could lead to SQL injection if - the string is not sanitized properly. Audit this call to ensure the - SQL is not manipulable by external data. - severity: WARNING - metadata: - owasp: "A1: Injection" - cwe: "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')" - source-rule-url: https://github.com/securego/gosec - category: security - technology: - - go - confidence: MEDIUM - patterns: - - pattern-not-inside: | - $VAR = "..." + "..." - ... - $OBJ.$SINK(..., $VAR, ...) - - pattern-not: $OBJ.Exec("...") - - pattern-not: $OBJ.ExecContext($CTX, "...") - - pattern-not: $OBJ.Query("...") - - pattern-not: $OBJ.QueryContext($CTX, "...") - - pattern-not: $OBJ.QueryRow("...") - - pattern-not: $OBJ.QueryRow($CTX, "...") - - pattern-not: $OBJ.QueryRowContext($CTX, "...") - - pattern-either: - - pattern: $OBJ.Exec($X + ...) - - pattern: $OBJ.ExecContext($CTX, $X + ...) - - pattern: $OBJ.Query($X + ...) - - pattern: $OBJ.QueryContext($CTX, $X + ...) - - pattern: $OBJ.QueryRow($X + ...) - - pattern: $OBJ.QueryRow($CTX, $X + ...) - - pattern: $OBJ.QueryRowContext($CTX, $X + ...) - - pattern: $OBJ.Exec(fmt.$P("...", ...)) - - pattern: $OBJ.ExecContext($CTX, fmt.$P("...", ...)) - - pattern: $OBJ.Query(fmt.$P("...", ...)) - - pattern: $OBJ.QueryContext($CTX, fmt.$P("...", ...)) - - pattern: $OBJ.QueryRow(fmt.$P("...", ...)) - - pattern: $OBJ.QueryRow($CTX, fmt.$P("...", ...)) - - pattern: $OBJ.QueryRowContext($CTX, fmt.$P("...", ...)) - - pattern: | - $QUERY = "..." - ... - $QUERY = $FXN(..., $QUERY, ...) - ... - $OBJ.Exec($QUERY, ...) - - pattern: | - $QUERY = "..." - ... - $QUERY = $FXN(..., $QUERY, ...) - ... - $OBJ.Query($QUERY, ...) - - pattern: | - $QUERY = "..." - ... - $QUERY = $FXN(..., $QUERY, ...) - ... - $OBJ.ExecContext($CTX, $QUERY, ...) - - pattern: | - $QUERY = "..." - ... - $QUERY = $FXN(..., $QUERY, ...) - ... - $OBJ.QueryContext($CTX, $QUERY, ...) - - pattern: | - $QUERY = "..." - ... - $QUERY = $FXN(..., $QUERY, ...) - ... - $OBJ.QueryRow($QUERY) - - pattern: | - $QUERY = "..." - ... - $QUERY = $FXN(..., $QUERY, ...) - ... - $OBJ.QueryRow($CTX, $QUERY) - - pattern: | - $QUERY = "..." - ... - $QUERY = $FXN(..., $QUERY, ...) - ... - $OBJ.QueryRowContext($CTX, $QUERY, ...) - - pattern: | - $QUERY = "..." - ... - $OTHER = $FXN(..., $QUERY, ...) - ... - $OBJ.Exec($OTHER, ...) - - pattern: | - $QUERY = "..." - ... - $OTHER = $FXN(..., $QUERY, ...) - ... - $OBJ.Query($OTHER, ...) - - pattern: | - $QUERY = "..." - ... - $OTHER = $FXN(..., $QUERY, ...) - ... - $OBJ.ExecContext($CTX, $OTHER, ...) - - pattern: | - $QUERY = "..." - ... - $OTHER = $FXN(..., $QUERY, ...) - ... - $OBJ.QueryContext($CTX, $OTHER, ...) - - pattern: | - $QUERY = "..." - ... - $OTHER = $FXN(..., $QUERY, ...) - ... - $OBJ.QueryRow($OTHER) - - pattern: | - $QUERY = "..." - ... - $OTHER = $FXN(..., $QUERY, ...) - ... - $OBJ.QueryRow($CTX, $OTHER) - - pattern: | - $QUERY = "..." - ... - $OTHER = $FXN(..., $QUERY, ...) - ... - $OBJ.QueryRowContext($CTX, $OTHER, ...) - - pattern: | - $QUERY = $X + ... - ... - $OBJ.Exec($QUERY, ...) - - pattern: | - $QUERY = $X + ... - ... - $OBJ.Query($QUERY, ...) - - pattern: | - $QUERY = $X + ... - ... - $OBJ.ExecContext($CTX, $QUERY, ...) - - pattern: | - $QUERY = $X + ... - ... - $OBJ.QueryContext($CTX, $QUERY, ...) - - pattern: | - $QUERY = $X + ... - ... - $OBJ.QueryRow($QUERY) - - pattern: | - $QUERY = $X + ... - ... - $OBJ.QueryRow($CTX, $QUERY) - - pattern: | - $QUERY = $X + ... - ... - $OBJ.QueryRowContext($CTX, $QUERY, ...) diff --git a/tests/semgrep/go/lang/security/audit/md5-used-as-password.yaml b/tests/semgrep/go/lang/security/audit/md5-used-as-password.yaml deleted file mode 100644 index d0b9923..0000000 --- a/tests/semgrep/go/lang/security/audit/md5-used-as-password.yaml +++ /dev/null @@ -1,35 +0,0 @@ -rules: - - id: md5-used-as-password - languages: [go] - severity: WARNING - message: >- - It looks like MD5 is used as a password hash. MD5 is not considered a - secure password hash because it can be cracked by an attacker in a short - amount of time. Use a suitable password hashing function such as bcrypt. - You can use the `golang.org/x/crypto/bcrypt` package. - metadata: - category: security - technology: - - md5 - references: - - https://tools.ietf.org/id/draft-lvelvindron-tls-md5-sha1-deprecate-01.html - - https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords - - https://github.com/returntocorp/semgrep-rules/issues/1609 - - https://pkg.go.dev/golang.org/x/crypto/bcrypt - owasp: - - A02:2017 - Broken Authentication - - A02:2021 - Cryptographic Failures - cwe: "CWE-327: Use of a Broken or Risky Cryptographic Algorithm" - confidence: HIGH - mode: taint - pattern-sources: - - patterns: - - pattern-either: - - pattern: md5.New - - pattern: md5.Sum - pattern-sinks: - - patterns: - - pattern: $FUNCTION(...) - - metavariable-regex: - metavariable: $FUNCTION - regex: (?i)(.*password.*) diff --git a/tests/semgrep/go/lang/security/audit/net/bind_all.yaml b/tests/semgrep/go/lang/security/audit/net/bind_all.yaml deleted file mode 100644 index 696828b..0000000 --- a/tests/semgrep/go/lang/security/audit/net/bind_all.yaml +++ /dev/null @@ -1,21 +0,0 @@ -rules: - - id: avoid-bind-to-all-interfaces - message: >- - Detected a network listener listening on 0.0.0.0 or an empty string. - This could unexpectedly expose the server publicly as it binds to all available interfaces. - Instead, specify another IP address that is not 0.0.0.0 nor the empty string. - languages: [go] - severity: WARNING - metadata: - cwe: "CWE-200: Exposure of Sensitive Information to an Unauthorized Actor" - owasp: "A6: Security Misconfiguration" - source-rule-url: https://github.com/securego/gosec - category: security - technology: - - go - confidence: MEDIUM - pattern-either: - - pattern: tls.Listen($NETWORK, "=~/^0.0.0.0:.*$/", ...) - - pattern: net.Listen($NETWORK, "=~/^0.0.0.0:.*$/", ...) - - pattern: tls.Listen($NETWORK, "=~/^:.*$/", ...) - - pattern: net.Listen($NETWORK, "=~/^:.*$/", ...) \ No newline at end of file diff --git a/tests/semgrep/go/lang/security/audit/net/cookie-missing-httponly.yaml b/tests/semgrep/go/lang/security/audit/net/cookie-missing-httponly.yaml deleted file mode 100644 index 50f2440..0000000 --- a/tests/semgrep/go/lang/security/audit/net/cookie-missing-httponly.yaml +++ /dev/null @@ -1,34 +0,0 @@ -rules: - - id: cookie-missing-httponly - patterns: - - pattern-not-inside: | - http.Cookie{ - ..., - HttpOnly: true, - ..., - } - - pattern: | - http.Cookie{ - ..., - } - message: >- - A session cookie was detected without setting the 'HttpOnly' flag. - The 'HttpOnly' flag for cookies instructs the browser to forbid - client-side scripts from reading the cookie which mitigates XSS - attacks. Set the 'HttpOnly' flag by setting 'HttpOnly' to 'true' - in the Cookie. - metadata: - cwe: "CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag" - owasp: "A3: Sensitive Data Exposure" - references: - - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/util/cookie.go - - https://golang.org/src/net/http/cookie.go - category: security - technology: - - go - confidence: MEDIUM - fix-regex: - regex: (HttpOnly\s*:\s+)false - replacement: \1true - severity: WARNING - languages: [go] diff --git a/tests/semgrep/go/lang/security/audit/net/cookie-missing-secure.yaml b/tests/semgrep/go/lang/security/audit/net/cookie-missing-secure.yaml deleted file mode 100644 index 95387b5..0000000 --- a/tests/semgrep/go/lang/security/audit/net/cookie-missing-secure.yaml +++ /dev/null @@ -1,33 +0,0 @@ -rules: - - id: cookie-missing-secure - patterns: - - pattern-not-inside: | - http.Cookie{ - ..., - Secure: true, - ..., - } - - pattern: | - http.Cookie{ - ..., - } - message: >- - A session cookie was detected without setting the 'Secure' flag. - The 'secure' flag for cookies prevents the client from transmitting - the cookie over insecure channels such as HTTP. Set the 'Secure' - flag by setting 'Secure' to 'true' in the Options struct. - metadata: - cwe: "CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute" - owasp: "A3: Sensitive Data Exposure" - references: - - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/util/cookie.go - - https://golang.org/src/net/http/cookie.go - category: security - technology: - - go - confidence: MEDIUM - fix-regex: - regex: (Secure\s*:\s+)false - replacement: \1true - severity: WARNING - languages: [go] diff --git a/tests/semgrep/go/lang/security/audit/net/dynamic-httptrace-clienttrace.yaml b/tests/semgrep/go/lang/security/audit/net/dynamic-httptrace-clienttrace.yaml deleted file mode 100644 index 3e1f803..0000000 --- a/tests/semgrep/go/lang/security/audit/net/dynamic-httptrace-clienttrace.yaml +++ /dev/null @@ -1,32 +0,0 @@ -rules: - - id: dynamic-httptrace-clienttrace - message: >- - Detected a potentially dynamic ClientTrace. This occurred because semgrep could - not - find a static definition for '$TRACE'. Dynamic ClientTraces are dangerous because - they deserialize function code to run when certain Request events occur, which - could lead - to code being run without your knowledge. Ensure that your ClientTrace is statically - defined. - metadata: - cwe: "CWE-913: Improper Control of Dynamically-Managed Code Resources" - owasp: "A8: Insecure Deserialization" - references: - - https://github.com/returntocorp/semgrep-rules/issues/518 - # Detects when a static ClientTrace is not defined in the same file as - # WithClientTrace. Not a perfect detection, but sufficiently works in a - # scan of ~1k repos: https://dev.massive.ret2.co/triager/filter/1007 - category: security - technology: - - go - confidence: MEDIUM - patterns: - - pattern-not-inside: | - package $PACKAGE - ... - &httptrace.ClientTrace { ... } - ... - - pattern: httptrace.WithClientTrace($ANY, $TRACE) - severity: WARNING - languages: - - go diff --git a/tests/semgrep/go/lang/security/audit/net/formatted-template-string.yaml b/tests/semgrep/go/lang/security/audit/net/formatted-template-string.yaml deleted file mode 100644 index 6987592..0000000 --- a/tests/semgrep/go/lang/security/audit/net/formatted-template-string.yaml +++ /dev/null @@ -1,47 +0,0 @@ -rules: - - id: formatted-template-string - message: >- - Found a formatted template string passed to 'template.HTML()'. - 'template.HTML()' does not escape contents. - Be absolutely sure there is no user-controlled data in this template. - If user data can reach this template, you may have a XSS vulnerability. - metadata: - cwe: "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')" - owasp: "A1: Injection" - references: - - https://golang.org/pkg/html/template/#HTML - category: security - technology: - - go - confidence: MEDIUM - languages: [go] - severity: WARNING - patterns: - - pattern-not: template.HTML("..." + "...") - - pattern-either: - - pattern: template.HTML($T + $X, ...) - - pattern: template.HTML(fmt.$P("...", ...), ...) - - pattern: | - $T = "..." - ... - $T = $FXN(..., $T, ...) - ... - template.HTML($T, ...) - - pattern: | - $T = fmt.$P("...", ...) - ... - template.HTML($T, ...) - - pattern: | - $T, $ERR = fmt.$P("...", ...) - ... - template.HTML($T, ...) - - pattern: | - $T = $X + $Y - ... - template.HTML($T, ...) - - pattern: | - $T = "..." - ... - $OTHER, $ERR = fmt.$P(..., $T, ...) - ... - template.HTML($OTHER, ...) \ No newline at end of file diff --git a/tests/semgrep/go/lang/security/audit/net/pprof.yaml b/tests/semgrep/go/lang/security/audit/net/pprof.yaml deleted file mode 100644 index 1b66f32..0000000 --- a/tests/semgrep/go/lang/security/audit/net/pprof.yaml +++ /dev/null @@ -1,35 +0,0 @@ -rules: - - id: pprof-debug-exposure - metadata: - cwe: "CWE-489: Active Debug Code" - owasp: "A6: Security Misconfiguration" - source-rule-url: https://github.com/securego/gosec#available-rules - references: - - https://www.farsightsecurity.com/blog/txt-record/go-remote-profiling-20161028/ - category: security - technology: - - go - confidence: MEDIUM - message: >- - The profiling 'pprof' endpoint is automatically exposed on /debug/pprof. - This could leak information about the server. - Instead, use `import "net/http/pprof"`. See - https://www.farsightsecurity.com/blog/txt-record/go-remote-profiling-20161028/ - for more information and mitigation. - languages: [go] - severity: WARNING - patterns: - - pattern-inside: | - import _ "net/http/pprof" - ... - - pattern-inside: | - func $ANY(...) { - ... - } - - pattern-not-inside: | - $MUX = http.NewServeMux(...) - ... - http.ListenAndServe($ADDR, $MUX) - - pattern-not: http.ListenAndServe("=~/^localhost.*/", ...) - - pattern-not: http.ListenAndServe("=~/^127[.]0[.]0[.]1.*/", ...) - - pattern: http.ListenAndServe(...) diff --git a/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-htmlattr.yaml b/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-htmlattr.yaml deleted file mode 100644 index 0c3235d..0000000 --- a/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-htmlattr.yaml +++ /dev/null @@ -1,47 +0,0 @@ -rules: - - id: unescaped-data-in-htmlattr - message: >- - Found a formatted template string passed to 'template. - HTMLAttr()'. 'template.HTMLAttr()' does not escape contents. - Be absolutely sure there is no user-controlled data in this template or - validate and sanitize the data before passing it into the template. - metadata: - cwe: - "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ - \ Scripting')" - owasp: "A1: Injection" - references: - - https://golang.org/pkg/html/template/#HTMLAttr - category: security - technology: - - go - confidence: MEDIUM - languages: [go] - severity: WARNING - pattern-either: - - pattern: template.HTMLAttr($T + $X, ...) - - pattern: template.HTMLAttr(fmt.$P("...", ...), ...) - - pattern: | - $T = "..." - ... - $T = $FXN(..., $T, ...) - ... - template.HTMLAttr($T, ...) - - pattern: | - $T = fmt.$P("...", ...) - ... - template.HTMLAttr($T, ...) - - pattern: | - $T, $ERR = fmt.$P("...", ...) - ... - template.HTMLAttr($T, ...) - - pattern: | - $T = $X + $Y - ... - template.HTMLAttr($T, ...) - - pattern: | - $T = "..." - ... - $OTHER, $ERR = fmt.$P(..., $T, ...) - ... - template.HTMLAttr($OTHER, ...) \ No newline at end of file diff --git a/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-js.yaml b/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-js.yaml deleted file mode 100644 index 3c7ed7e..0000000 --- a/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-js.yaml +++ /dev/null @@ -1,46 +0,0 @@ -rules: - - id: unescaped-data-in-js - message: >- - Found a formatted template string passed to 'template.JS()'. - 'template.JS()' does not escape contents. Be absolutely sure - there is no user-controlled data in this template. - metadata: - cwe: - "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ - \ Scripting')" - owasp: "A1: Injection" - references: - - https://golang.org/pkg/html/template/#JS - category: security - technology: - - go - confidence: MEDIUM - languages: [go] - severity: WARNING - pattern-either: - - pattern: template.JS($T + $X, ...) - - pattern: template.JS(fmt.$P("...", ...), ...) - - pattern: | - $T = "..." - ... - $T = $FXN(..., $T, ...) - ... - template.JS($T, ...) - - pattern: | - $T = fmt.$P("...", ...) - ... - template.JS($T, ...) - - pattern: | - $T, $ERR = fmt.$P("...", ...) - ... - template.JS($T, ...) - - pattern: | - $T = $X + $Y - ... - template.JS($T, ...) - - pattern: | - $T = "..." - ... - $OTHER, $ERR = fmt.$P(..., $T, ...) - ... - template.JS($OTHER, ...) diff --git a/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-url.yaml b/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-url.yaml deleted file mode 100644 index a9bc14b..0000000 --- a/tests/semgrep/go/lang/security/audit/net/unescaped-data-in-url.yaml +++ /dev/null @@ -1,48 +0,0 @@ -rules: - - id: unescaped-data-in-url - message: >- - Found a formatted template string passed to 'template.URL()'. - 'template.URL()' does not escape contents, and this could result in XSS (cross-site scripting) - and therefore confidential data being stolen. - Sanitize data coming into this function or make sure that - no user-controlled input is coming into the function. - metadata: - cwe: - "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ - \ Scripting')" - owasp: "A1: Injection" - references: - - https://golang.org/pkg/html/template/#URL - category: security - technology: - - go - confidence: MEDIUM - languages: [go] - severity: WARNING - pattern-either: - - pattern: template.URL($T + $X, ...) - - pattern: template.URL(fmt.$P("...", ...), ...) - - pattern: | - $T = "..." - ... - $T = $FXN(..., $T, ...) - ... - template.URL($T, ...) - - pattern: | - $T = fmt.$P("...", ...) - ... - template.URL($T, ...) - - pattern: | - $T, $ERR = fmt.$P("...", ...) - ... - template.URL($T, ...) - - pattern: | - $T = $X + $Y - ... - template.URL($T, ...) - - pattern: | - $T = "..." - ... - $OTHER, $ERR = fmt.$P(..., $T, ...) - ... - template.URL($OTHER, ...) \ No newline at end of file diff --git a/tests/semgrep/go/lang/security/audit/net/use-tls.yaml b/tests/semgrep/go/lang/security/audit/net/use-tls.yaml deleted file mode 100644 index ecba4b5..0000000 --- a/tests/semgrep/go/lang/security/audit/net/use-tls.yaml +++ /dev/null @@ -1,18 +0,0 @@ -rules: - - id: use-tls - pattern: http.ListenAndServe($ADDR, $HANDLER) - fix: http.ListenAndServeTLS($ADDR, certFile, keyFile, $HANDLER) - metadata: - cwe: "CWE-319: Cleartext Transmission of Sensitive Information" - owasp: "A3: Sensitive Data Exposure" - references: - - https://golang.org/pkg/net/http/#ListenAndServeTLS - category: security - technology: - - go - confidence: MEDIUM - message: >- - Found an HTTP server without TLS. Use 'http.ListenAndServeTLS' instead. - See https://golang.org/pkg/net/http/#ListenAndServeTLS for more information. - languages: [go] - severity: WARNING diff --git a/tests/semgrep/go/lang/security/audit/net/wip-xss-using-responsewriter-and-printf.yaml b/tests/semgrep/go/lang/security/audit/net/wip-xss-using-responsewriter-and-printf.yaml deleted file mode 100644 index 5692cc5..0000000 --- a/tests/semgrep/go/lang/security/audit/net/wip-xss-using-responsewriter-and-printf.yaml +++ /dev/null @@ -1,61 +0,0 @@ -rules: - - id: wip-xss-using-responsewriter-and-printf - patterns: - - pattern-inside: | - func $FUNC(..., $W http.ResponseWriter, ...) { - ... - var $TEMPLATE = "..." - ... - $W.Write([]byte(fmt.$PRINTF($TEMPLATE, ...)), ...) - ... - } - - pattern-either: - - pattern: | - $PARAMS = r.URL.Query() - ... - $DATA, $ERR := $PARAMS[...] - ... - $INTERM = $ANYTHING(..., $DATA, ...) - ... - $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) - - pattern: | - $PARAMS = r.URL.Query() - ... - $DATA, $ERR := $PARAMS[...] - ... - $INTERM = $DATA[...] - ... - $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) - - pattern: | - $DATA, $ERR := r.URL.Query()[...] - ... - $INTERM = $DATA[...] - ... - $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) - - pattern: | - $DATA, $ERR := r.URL.Query()[...] - ... - $INTERM = $ANYTHING(..., $DATA, ...) - ... - $W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...))) - - pattern: | - $PARAMS = r.URL.Query() - ... - $DATA, $ERR := $PARAMS[...] - ... - $W.Write([]byte(fmt.$PRINTF(..., $DATA, ...))) - message: >- - Found data going from url query parameters into formatted data written to ResponseWriter. - This could be XSS and should not be done. If you must do this, ensure your data - is - sanitized or escaped. - metadata: - cwe: "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')" - owasp: "A7: Cross-Site Scripting (XSS)" - category: security - technology: - - go - confidence: MEDIUM - severity: WARNING - languages: - - go diff --git a/tests/semgrep/go/lang/security/audit/reflect-makefunc.yaml b/tests/semgrep/go/lang/security/audit/reflect-makefunc.yaml deleted file mode 100644 index 87a8407..0000000 --- a/tests/semgrep/go/lang/security/audit/reflect-makefunc.yaml +++ /dev/null @@ -1,18 +0,0 @@ -rules: - - id: reflect-makefunc - message: >- - 'reflect.MakeFunc' detected. This will sidestep protections that are - normally afforded by Go's type system. Audit this call and be sure that - user input cannot be used to affect the code generated by MakeFunc; - otherwise, you will have a serious security vulnerability. - metadata: - owasp: "A8: Insecure Deserialization" - cwe: "CWE-913: Improper Control of Dynamically-Managed Code Resources" - category: security - technology: - - go - confidence: MEDIUM - severity: ERROR - pattern: reflect.MakeFunc(...) - languages: - - go diff --git a/tests/semgrep/go/lang/security/audit/sqli/gosql-sqli.yaml b/tests/semgrep/go/lang/security/audit/sqli/gosql-sqli.yaml deleted file mode 100644 index a4c9dfd..0000000 --- a/tests/semgrep/go/lang/security/audit/sqli/gosql-sqli.yaml +++ /dev/null @@ -1,52 +0,0 @@ -rules: - - id: gosql-sqli - patterns: - - pattern-either: - - patterns: - - pattern: $DB.$METHOD(...,$QUERY,...) - - pattern-either: - - pattern-inside: | - $QUERY = $X + $Y - ... - - pattern-inside: | - $QUERY += $X - ... - - pattern-inside: | - $QUERY = fmt.Sprintf("...", $PARAM1, ...) - ... - - pattern-not-inside: | - $QUERY += "..." - ... - - pattern-not-inside: | - $QUERY = "..." + "..." - ... - - pattern: $DB.$METHOD(..., $X + $Y, ...) - - pattern: $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...) - - pattern-either: - - pattern-inside: | - $DB, ... = sql.Open(...) - ... - - pattern-inside: | - func $FUNCNAME(..., $DB *sql.DB, ...) { - ... - } - - pattern-not: $DB.$METHOD(..., "..." + "...", ...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(Exec|ExecContent|Query|QueryContext|QueryRow|QueryRowContext)$ - languages: - - go - message: >- - Detected string concatenation with a non-literal variable in a "database/sql" - Go SQL statement. This could lead to SQL injection if the variable is user-controlled - and not properly sanitized. In order to prevent SQL injection, - used parameterized queries or prepared statements instead. - You can use prepared statements with the 'Prepare' and 'PrepareContext' calls. - metadata: - references: - - https://golang.org/pkg/database/sql/ - category: security - technology: - - go - confidence: MEDIUM - severity: ERROR diff --git a/tests/semgrep/go/lang/security/audit/sqli/pg-orm-sqli.yaml b/tests/semgrep/go/lang/security/audit/sqli/pg-orm-sqli.yaml deleted file mode 100644 index 085758b..0000000 --- a/tests/semgrep/go/lang/security/audit/sqli/pg-orm-sqli.yaml +++ /dev/null @@ -1,55 +0,0 @@ -rules: - - id: pg-orm-sqli - patterns: - - pattern-either: - - patterns: - - pattern: $DB.$METHOD(...,$QUERY,...) - - pattern-either: - - pattern-inside: | - $QUERY = $X + $Y - ... - - pattern-inside: | - $QUERY += $X - ... - - pattern-inside: | - $QUERY = fmt.Sprintf("...", $PARAM1, ...) - ... - - pattern-not-inside: | - $QUERY += "..." - ... - - pattern-not-inside: | - $QUERY = "..." + "..." - ... - - pattern: | - $DB.$INTFUNC1(...).$METHOD(..., $X + $Y, ...).$INTFUNC2(...) - - pattern: | - $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...) - - pattern-inside: | - $DB = pg.Connect(...) - ... - - pattern-inside: | - func $FUNCNAME(..., $DB *pg.DB, ...) { - ... - } - - pattern-not: | - $DB.$INTFUNC1(...).$METHOD(..., "..." + "...", ...).$INTFUNC2(...) - - pattern-not: path.Join(...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(Where|WhereOr|Join|GroupExpr|OrderExpr|ColumnExpr)$ - languages: - - go - message: >- - Detected string concatenation with a non-literal variable in a go-pg ORM - SQL statement. This could lead to SQL injection if the variable is user-controlled - and not properly sanitized. In order to prevent SQL injection, - do not use strings concatenated with user-controlled input. - Instead, use parameterized statements. - metadata: - references: - - https://pg.uptrace.dev/queries/ - category: security - technology: - - go-pg - confidence: MEDIUM - severity: ERROR diff --git a/tests/semgrep/go/lang/security/audit/sqli/pg-sqli.yaml b/tests/semgrep/go/lang/security/audit/sqli/pg-sqli.yaml deleted file mode 100644 index 0454374..0000000 --- a/tests/semgrep/go/lang/security/audit/sqli/pg-sqli.yaml +++ /dev/null @@ -1,55 +0,0 @@ -rules: - - id: pg-sqli - languages: - - go - message: >- - Detected string concatenation with a non-literal variable in a go-pg - SQL statement. This could lead to SQL injection if the variable is user-controlled - and not properly sanitized. In order to prevent SQL injection, - used parameterized queries instead of string concatenation. You can use parameterized - queries like so: - '(SELECT ? FROM table, data1)' - metadata: - references: - - https://pg.uptrace.dev/ - - https://pkg.go.dev/github.com/go-pg/pg/v10 - category: security - technology: - - go-pg - confidence: MEDIUM - severity: ERROR - patterns: - - pattern-either: - - patterns: - - pattern: | - $DB.$METHOD(...,$QUERY,...) - - pattern-either: - - pattern-inside: | - $QUERY = $X + $Y - ... - - pattern-inside: | - $QUERY += $X - ... - - pattern-inside: | - $QUERY = fmt.Sprintf("...", $PARAM1, ...) - ... - - pattern-not-inside: | - $QUERY += "..." - ... - - pattern-not-inside: | - $QUERY = "..." + "..." - ... - - pattern: $DB.$METHOD(..., $X + $Y, ...) - - pattern: $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...) - - pattern-either: - - pattern-inside: | - $DB = pg.Connect(...) - ... - - pattern-inside: | - func $FUNCNAME(..., $DB *pg.DB, ...) { - ... - } - - pattern-not: $DB.$METHOD(..., "..." + "...", ...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(Exec|ExecContext|ExecOne|ExecOneContext|Query|QueryOne|QueryContext|QueryOneContext)$ diff --git a/tests/semgrep/go/lang/security/audit/sqli/pgx-sqli.yaml b/tests/semgrep/go/lang/security/audit/sqli/pgx-sqli.yaml deleted file mode 100644 index 24bba65..0000000 --- a/tests/semgrep/go/lang/security/audit/sqli/pgx-sqli.yaml +++ /dev/null @@ -1,59 +0,0 @@ -rules: - - id: pgx-sqli - languages: - - go - message: >- - Detected string concatenation with a non-literal variable in a pgx - Go SQL statement. This could lead to SQL injection if the variable is user-controlled - and not properly sanitized. In order to prevent SQL injection, - used parameterized queries instead. You can use parameterized queries like so: - (`SELECT $1 FROM table`, `data1) - metadata: - references: - - https://github.com/jackc/pgx - - https://pkg.go.dev/github.com/jackc/pgx/v4#hdr-Connection_Pool - category: security - technology: - - pgx - confidence: MEDIUM - patterns: - - pattern-either: - - patterns: - - pattern: $DB.$METHOD(...,$QUERY,...) - - pattern-either: - - pattern-inside: | - $QUERY = $X + $Y - ... - - pattern-inside: | - $QUERY += $X - ... - - pattern-inside: | - $QUERY = fmt.Sprintf("...", $PARAM1, ...) - ... - - pattern-not-inside: | - $QUERY += "..." - ... - - pattern-not-inside: | - $QUERY = "..." + "..." - ... - - pattern: $DB.$METHOD(..., $X + $Y, ...) - - pattern: $DB.$METHOD(..., fmt.Sprintf("...", $PARAM1, ...), ...) - - pattern-either: - - pattern-inside: | - $DB, ... = pgx.Connect(...) - ... - - pattern-inside: | - $DB, ... = pgx.NewConnPool(...) - ... - - pattern-inside: | - $DB, ... = pgx.ConnectConfig(...) - ... - - pattern-inside: | - func $FUNCNAME(..., $DB *pgx.Conn, ...) { - ... - } - - pattern-not: $DB.$METHOD(..., "..." + "...", ...) - - metavariable-regex: - metavariable: $METHOD - regex: ^(Exec|ExecEx|Query|QueryEx|QueryRow|QueryRowEx)$ - severity: ERROR diff --git a/tests/semgrep/go/lang/security/audit/unsafe-reflect-by-name.yaml b/tests/semgrep/go/lang/security/audit/unsafe-reflect-by-name.yaml deleted file mode 100644 index 0bddd02..0000000 --- a/tests/semgrep/go/lang/security/audit/unsafe-reflect-by-name.yaml +++ /dev/null @@ -1,34 +0,0 @@ -rules: - - id: unsafe-reflect-by-name - patterns: - - pattern-either: - - pattern: | - $SMTH.MethodByName($NAME,...) - - pattern: | - $SMTH.FieldByName($NAME,...) - - pattern-not: | - $SMTH.MethodByName("...",...) - - pattern-not: | - $SMTH.FieldByName("...",...) - - pattern-inside: | - import "reflect" - ... - message: >- - If an attacker can supply values that the application then uses to determine which - method or field to invoke, - the potential exists for the attacker to create control flow paths through the - application - that were not intended by the application developers. - This attack vector may allow the attacker to bypass authentication or access control - checks - or otherwise cause the application to behave in an unexpected manner. - metadata: - cwe: "CWE-470: Use of Externally-Controlled Input to Select Classes or Code ('Unsafe Reflection')" - owasp: "A1: Injection" - category: security - technology: - - go - confidence: MEDIUM - severity: WARNING - languages: - - go diff --git a/tests/semgrep/go/lang/security/audit/unsafe.yaml b/tests/semgrep/go/lang/security/audit/unsafe.yaml deleted file mode 100644 index 864f165..0000000 --- a/tests/semgrep/go/lang/security/audit/unsafe.yaml +++ /dev/null @@ -1,17 +0,0 @@ -rules: - - id: use-of-unsafe-block - message: >- - Using the unsafe package in Go gives you low-level memory management - and many of the strengths of the C language, but also steps around the type safety of Go - and can lead to buffer overflows and possible arbitrary code execution by an attacker. - Only use this package if you absolutely know what you're doing. - languages: [go] - severity: WARNING - metadata: - cwe: "CWE-242: Use of Inherently Dangerous Function" - source_rule_url: https://github.com/securego/gosec/blob/master/rules/unsafe.go - category: security - technology: - - go - confidence: MEDIUM - pattern: unsafe.$FUNC(...) diff --git a/tests/semgrep/go/lang/security/audit/xss/import-text-template.yaml b/tests/semgrep/go/lang/security/audit/xss/import-text-template.yaml deleted file mode 100644 index 99faa68..0000000 --- a/tests/semgrep/go/lang/security/audit/xss/import-text-template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -rules: - - id: import-text-template - message: >- - 'text/template' does not escape HTML content. If you need - to escape HTML content, use 'html/template' instead. - metadata: - owasp: "A7: Cross-Site Scripting (XSS)" - cwe: - "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ - \ Scripting')" - references: - - https://www.veracode.com/blog/secure-development/use-golang-these-mistakes-could-compromise-your-apps-security - category: security - technology: - - go - confidence: MEDIUM - severity: WARNING - pattern: | - import "text/template" - languages: - - go diff --git a/tests/semgrep/go/lang/security/audit/xss/no-direct-write-to-responsewriter.yaml b/tests/semgrep/go/lang/security/audit/xss/no-direct-write-to-responsewriter.yaml deleted file mode 100644 index ea22ad1..0000000 --- a/tests/semgrep/go/lang/security/audit/xss/no-direct-write-to-responsewriter.yaml +++ /dev/null @@ -1,40 +0,0 @@ -rules: - - id: no-direct-write-to-responsewriter - languages: - - go - message: >- - Detected directly writing or similar in 'http.ResponseWriter.write()'. - This bypasses HTML escaping that prevents cross-site scripting - vulnerabilities. Instead, use the 'html/template' package - and render data using 'template.Execute()'. - metadata: - category: security - cwe: - "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ - \ Scripting')" - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - owasp: "A7: Cross-Site Scripting (XSS)" - references: - - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ - technology: - - go - confidence: MEDIUM - patterns: - - pattern-either: - - pattern-inside: | - func $HANDLER(..., $WRITER http.ResponseWriter, ...) { - ... - } - - pattern-inside: | - func $HANDLER(..., $WRITER *http.ResponseWriter, ...) { - ... - } - - pattern-inside: | - func(..., $WRITER http.ResponseWriter, ...) { - ... - } - - pattern-either: - - pattern: $WRITER.Write(...) - - pattern: (*$WRITER).Write(...) - - pattern-not: $WRITER.Write([]byte("...")) - severity: WARNING diff --git a/tests/semgrep/go/lang/security/audit/xss/no-fprintf-to-responsewriter.yaml b/tests/semgrep/go/lang/security/audit/xss/no-fprintf-to-responsewriter.yaml deleted file mode 100644 index a990aaa..0000000 --- a/tests/semgrep/go/lang/security/audit/xss/no-fprintf-to-responsewriter.yaml +++ /dev/null @@ -1,33 +0,0 @@ -rules: - - id: no-fprintf-to-responsewriter - message: >- - Detected 'Fprintf' or similar writing to 'http.ResponseWriter'. - This bypasses HTML escaping that prevents cross-site scripting - vulnerabilities. Instead, use the 'html/template' package - to render data to users. - metadata: - owasp: "A7: Cross-Site Scripting (XSS)" - cwe: - "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ - \ Scripting')" - references: - - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ - category: security - technology: - - go - confidence: MEDIUM - severity: WARNING - patterns: - - pattern-either: - - pattern-inside: | - func $HANDLER(..., $WRITER http.ResponseWriter, ...) { - ... - } - - pattern-inside: | - func(..., $WRITER http.ResponseWriter, ...) { - ... - } - - pattern-not: fmt.$PRINTF($WRITER, "...") - - pattern: fmt.$PRINTF($WRITER, ...) - languages: - - go diff --git a/tests/semgrep/go/lang/security/audit/xss/no-interpolation-in-tag.yaml b/tests/semgrep/go/lang/security/audit/xss/no-interpolation-in-tag.yaml deleted file mode 100644 index f205a70..0000000 --- a/tests/semgrep/go/lang/security/audit/xss/no-interpolation-in-tag.yaml +++ /dev/null @@ -1,24 +0,0 @@ -rules: - - id: no-interpolation-in-tag - message: >- - Detected template variable interpolation in an HTML tag. - This is potentially vulnerable to cross-site scripting (XSS) - attacks because a malicious actor has control over HTML - but without the need to use escaped characters. Use explicit - tags instead. - metadata: - cwe: - "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ - \ Scripting')" - owasp: "A7: Cross-Site Scripting (XSS)" - references: - - https://github.com/golang/go/issues/19669 - - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ - category: security - technology: - - generic - confidence: MEDIUM - languages: - - generic - severity: WARNING - pattern: <{{ ... }} ... > diff --git a/tests/semgrep/go/lang/security/audit/xss/no-interpolation-js-template-string.yaml b/tests/semgrep/go/lang/security/audit/xss/no-interpolation-js-template-string.yaml deleted file mode 100644 index 7a193db..0000000 --- a/tests/semgrep/go/lang/security/audit/xss/no-interpolation-js-template-string.yaml +++ /dev/null @@ -1,28 +0,0 @@ -rules: - - id: no-interpolation-js-template-string - message: >- - Detected template variable interpolation in a JavaScript - template string. This is potentially vulnerable to - cross-site scripting (XSS) attacks because a malicious - actor has control over JavaScript but without the need - to use escaped characters. Instead, obtain this variable - outside of the template string and ensure your template - is properly escaped. - metadata: - cwe: - "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ - \ Scripting')" - owasp: "A7: Cross-Site Scripting (XSS)" - references: - - https://github.com/golang/go/issues/9200#issuecomment-66100328 - - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ - category: security - technology: - - generic - confidence: MEDIUM - languages: - - generic - severity: WARNING - patterns: - - pattern-inside: - - pattern: "` ... {{ ... }} ...`" diff --git a/tests/semgrep/go/lang/security/audit/xss/no-io-writestring-to-responsewriter.yaml b/tests/semgrep/go/lang/security/audit/xss/no-io-writestring-to-responsewriter.yaml deleted file mode 100644 index 77edbbd..0000000 --- a/tests/semgrep/go/lang/security/audit/xss/no-io-writestring-to-responsewriter.yaml +++ /dev/null @@ -1,34 +0,0 @@ -rules: - - id: no-io-writestring-to-responsewriter - message: >- - Detected 'io.WriteString()' writing directly to 'http.ResponseWriter'. - This bypasses HTML escaping that prevents cross-site scripting - vulnerabilities. Instead, use the 'html/template' package - to render data to users. - metadata: - owasp: "A7: Cross-Site Scripting (XSS)" - cwe: - "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ - \ Scripting')" - references: - - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ - - https://golang.org/pkg/io/#WriteString - category: security - technology: - - go - confidence: MEDIUM - severity: WARNING - patterns: - - pattern-either: - - pattern-inside: | - func $HANDLER(..., $WRITER http.ResponseWriter, ...) { - ... - } - - pattern-inside: | - func(..., $WRITER http.ResponseWriter, ...) { - ... - } - - pattern-not: io.WriteString($WRITER, "...") - - pattern: io.WriteString($WRITER, $STRING) - languages: - - go diff --git a/tests/semgrep/go/lang/security/audit/xss/no-printf-in-responsewriter.yaml b/tests/semgrep/go/lang/security/audit/xss/no-printf-in-responsewriter.yaml deleted file mode 100644 index 6e8790c..0000000 --- a/tests/semgrep/go/lang/security/audit/xss/no-printf-in-responsewriter.yaml +++ /dev/null @@ -1,33 +0,0 @@ -rules: - - id: no-printf-in-responsewriter - message: >- - Detected 'printf' or similar in 'http.ResponseWriter.write()'. - This bypasses HTML escaping that prevents cross-site scripting - vulnerabilities. Instead, use the 'html/template' package - to render data to users. - metadata: - owasp: "A7: Cross-Site Scripting (XSS)" - cwe: - "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ - \ Scripting')" - references: - - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ - category: security - technology: - - go - confidence: MEDIUM - severity: WARNING - patterns: - - pattern-either: - - pattern-inside: | - func $HANDLER(..., $WRITER http.ResponseWriter, ...) { - ... - } - - pattern-inside: | - func(..., $WRITER http.ResponseWriter, ...) { - ... - } - - pattern: | - $WRITER.Write(<... fmt.$PRINTF(...) ...>, ...) - languages: - - go diff --git a/tests/semgrep/go/lang/security/audit/xss/template-html-does-not-escape.yaml b/tests/semgrep/go/lang/security/audit/xss/template-html-does-not-escape.yaml deleted file mode 100644 index aa5c2cf..0000000 --- a/tests/semgrep/go/lang/security/audit/xss/template-html-does-not-escape.yaml +++ /dev/null @@ -1,34 +0,0 @@ -rules: - - id: unsafe-template-type - message: >- - Semgrep could not determine that the argument to 'template.HTML()' - is a constant. 'template.HTML()' and similar does not escape contents. - Be absolutely sure there is no user-controlled data in this - template. If user data can reach this template, you may have - a XSS vulnerability. Instead, do not use this function and - use 'template.Execute()'. - metadata: - cwe: - "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ - \ Scripting')" - owasp: "A7: Cross-Site Scripting (XSS)" - references: - - https://golang.org/pkg/html/template/#HTML - - https://github.com/0c34/govwa/blob/139693e56406b5684d2a6ae22c0af90717e149b8/vulnerability/xss/xss.go#L33 - category: security - technology: - - go - confidence: MEDIUM - languages: [go] - severity: WARNING - patterns: - - pattern-not: template.$ANY("..." + "...") - - pattern-not: template.$ANY("...") - - pattern-either: - - pattern: template.HTML(...) - - pattern: template.CSS(...) - - pattern: template.HTMLAttr(...) - - pattern: template.JS(...) - - pattern: template.JSStr(...) - - pattern: template.Srcset(...) - - pattern: template.URL(...) diff --git a/tests/semgrep/go/lang/security/bad_tmp.yaml b/tests/semgrep/go/lang/security/bad_tmp.yaml deleted file mode 100644 index 046abde..0000000 --- a/tests/semgrep/go/lang/security/bad_tmp.yaml +++ /dev/null @@ -1,15 +0,0 @@ -rules: - - id: bad-tmp-file-creation - message: File creation in shared tmp directory without using ioutil.Tempfile - languages: [go] - severity: WARNING - metadata: - cwe: "CWE-377: Insecure Temporary File" - source-rule-url: https://github.com/securego/gosec - category: security - technology: - - go - confidence: MEDIUM - pattern-either: - - pattern: ioutil.WriteFile("=~//tmp/.*$/", ...) - - pattern: os.Create("=~//tmp/.*$/", ...) diff --git a/tests/semgrep/go/lang/security/decompression_bomb.yaml b/tests/semgrep/go/lang/security/decompression_bomb.yaml deleted file mode 100644 index fc34332..0000000 --- a/tests/semgrep/go/lang/security/decompression_bomb.yaml +++ /dev/null @@ -1,59 +0,0 @@ -rules: - - id: potential-dos-via-decompression-bomb - message: >- - Detected a possible denial-of-service via a zip bomb attack. By limiting the max - bytes read, you can mitigate this attack. - `io.CopyN()` can specify a size. Refer to https://bomb.codes/ to learn more about - this attack and other ways to mitigate - it. - severity: WARNING - languages: [go] - patterns: - - pattern-either: - - pattern: io.Copy(...) - - pattern: io.CopyBuffer(...) - - pattern-either: - - pattern-inside: | - gzip.NewReader(...) - ... - - pattern-inside: | - zlib.NewReader(...) - ... - - pattern-inside: | - zlib.NewReaderDict(...) - ... - - pattern-inside: | - bzip2.NewReader(...) - ... - - pattern-inside: | - flate.NewReader(...) - ... - - pattern-inside: | - flate.NewReaderDict(...) - ... - - pattern-inside: | - lzw.NewReader(...) - ... - - pattern-inside: | - tar.NewReader(...) - ... - - pattern-inside: | - zip.NewReader(...) - ... - - pattern-inside: | - zip.OpenReader(...) - ... - fix-regex: - regex: (.*)(Copy|CopyBuffer)\((.*?),(.*?)(\)|,.*\)) - replacement: \1CopyN(\3, \4, 1024*1024*256) - metadata: - cwe: "CWE-400: Uncontrolled Resource Consumption" - source-rule-url: https://github.com/securego/gosec - references: - - https://bomb.codes/ - - https://golang.org/pkg/io/#CopyN - - https://github.com/securego/gosec/blob/master/rules/decompression-bomb.go - category: security - technology: - - go - confidence: MEDIUM diff --git a/tests/semgrep/go/lang/security/filepath-clean-misuse.yaml b/tests/semgrep/go/lang/security/filepath-clean-misuse.yaml deleted file mode 100644 index e72f698..0000000 --- a/tests/semgrep/go/lang/security/filepath-clean-misuse.yaml +++ /dev/null @@ -1,41 +0,0 @@ -rules: -- id: filepath-clean-misuse - message: >- - `Clean` is not intended to sanitize against path traversal attacks. - This function is for finding the shortest path name equivalent to the given input. - Using `Clean` to sanitize file reads may expose this application to - path traversal attacks, where an attacker could access arbitrary files on the server. - To fix this easily, write this: `filepath.FromSlash(path.Clean("/"+strings.Trim(req.URL.Path, "/")))` - However, a better solution is using the `SecureJoin` function in the package `filepath-securejoin`. - See https://pkg.go.dev/github.com/cyphar/filepath-securejoin#section-readme. - severity: ERROR - languages: [go] - mode: taint - pattern-sources: - - pattern-either: - - pattern: "($REQUEST : *http.Request).$ANYTHING" - - pattern: "($REQUEST : http.Request).$ANYTHING" - pattern-sinks: - - patterns: - - pattern-either: - - pattern: filepath.Clean($...INNER) - - pattern: path.Clean($...INNER) - pattern-sanitizers: - - pattern-either: - - pattern: | - "/" + ... - fix: filepath.FromSlash(filepath.Clean("/"+strings.Trim($...INNER, "/"))) - metadata: - references: - - https://pkg.go.dev/path#Clean - - http://technosophos.com/2016/03/31/go-quickly-cleaning-filepaths.html - - https://labs.detectify.com/2021/12/15/zero-day-path-traversal-grafana/ - - https://dzx.cz/2021/04/02/go_path_traversal/ - - https://pkg.go.dev/github.com/cyphar/filepath-securejoin#section-readme - cwe: 'CWE-22: Path Traversal' - owasp: - - 'A03:2021 - Injection' - - 'A01:2017 - Injection' - category: security - technology: - - go diff --git a/tests/semgrep/go/lang/security/injection/raw-html-format.yaml b/tests/semgrep/go/lang/security/injection/raw-html-format.yaml deleted file mode 100644 index 1e6abab..0000000 --- a/tests/semgrep/go/lang/security/injection/raw-html-format.yaml +++ /dev/null @@ -1,47 +0,0 @@ -rules: - - id: raw-html-format - languages: [go] - severity: WARNING - message: >- - Detected user input flowing into a manually constructed HTML string. You may be - accidentally bypassing secure methods - of rendering HTML by manually constructing HTML and this could create a cross-site - scripting vulnerability, which could - let attackers steal sensitive user data. Use the `html/template` package which - will safely render HTML instead, or inspect - that the HTML is rendered safely. - metadata: - cwe: - "CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site\ - \ Scripting')" - owasp: - - A07:2017 - - A03:2021 - category: security - technology: - - go - references: - - https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/ - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - confidence: HIGH - mode: taint - pattern-sanitizers: - - pattern: html.EscapeString(...) - pattern-sources: - - patterns: - - pattern-either: - - pattern: "($REQUEST : *http.Request).$ANYTHING" - - pattern: "($REQUEST : http.Request).$ANYTHING" - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: fmt.Printf("$HTMLSTR", ...) - - pattern: fmt.Sprintf("$HTMLSTR", ...) - - pattern: fmt.Fprintf($W, "$HTMLSTR", ...) - - pattern: '"$HTMLSTR" + ...' - - metavariable-pattern: - metavariable: $HTMLSTR - language: generic - pattern: <$TAG ... diff --git a/tests/semgrep/go/lang/security/injection/tainted-sql-string.yaml b/tests/semgrep/go/lang/security/injection/tainted-sql-string.yaml deleted file mode 100644 index 80dc91c..0000000 --- a/tests/semgrep/go/lang/security/injection/tainted-sql-string.yaml +++ /dev/null @@ -1,50 +0,0 @@ -rules: - - id: tainted-sql-string - languages: [go] - message: >- - User data flows into this manually-constructed SQL string. User data - can be safely inserted into SQL strings using prepared statements or an - object-relational mapper (ORM). Manually-constructed SQL strings is a - possible indicator of SQL injection, which could let an attacker steal - or manipulate data from the database. - Instead, use prepared statements (`db.Query("SELECT * FROM t WHERE id = ?", id)`) - or a safe library. - metadata: - cwe: - "CWE-89: Improper Neutralization of Special Elements used in an SQL Command\ - \ ('SQL Injection')" - owasp: - - A10:2021 - - A01:2017 - references: - - https://golang.org/doc/database/sql-injection - - https://www.stackhawk.com/blog/golang-sql-injection-guide-examples-and-prevention/ - category: security - technology: - - go - confidence: HIGH - mode: taint - severity: WARNING - pattern-sources: - - pattern-either: - - pattern: "($REQUEST : *http.Request).$ANYTHING" - - pattern: "($REQUEST : http.Request).$ANYTHING" - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern: | - "$SQLSTR" + ... - - metavariable-regex: - metavariable: $SQLSTR - regex: (?i)(select|delete|insert|create|update|alter|drop).* - - patterns: - - pattern-either: - - pattern: fmt.Fprintf($F, "$SQLSTR", ...) - - pattern: fmt.Sprintf("$SQLSTR", ...) - - pattern: fmt.Printf("$SQLSTR", ...) - - metavariable-regex: - metavariable: $SQLSTR - regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.*%(v|s|q).* - pattern-sanitizers: - - pattern: strconv.Atoi(...) diff --git a/tests/semgrep/go/lang/security/injection/tainted-url-host.yaml b/tests/semgrep/go/lang/security/injection/tainted-url-host.yaml deleted file mode 100644 index 9df1aee..0000000 --- a/tests/semgrep/go/lang/security/injection/tainted-url-host.yaml +++ /dev/null @@ -1,46 +0,0 @@ -rules: - - id: tainted-url-host - languages: - - go - message: - User data flows into the host portion of this manually-constructed URL. - This could allow an attacker to send data to their own server, potentially exposing - sensitive data such as cookies or authorization information sent with this request. - They could also probe internal servers or other resources that the server runnig - this code can access. (This is called server-side request forgery, or SSRF.) Do - not allow arbitrary hosts. Instead, create an allowlist for approved hosts hardcode - the correct host. - metadata: - cwe: "CWE-918: Server-Side Request Forgery (SSRF)" - owasp: - - A10:2021 - - A01:2017 - references: - - https://goteleport.com/blog/ssrf-attacks/ - category: security - technology: - - go - license: Commons Clause License Condition v1.0[LGPL-2.1-only] - confidence: HIGH - mode: taint - pattern-sinks: - - patterns: - - pattern-either: - - patterns: - - pattern-either: - - pattern: fmt.Fprintf($F, "$URLSTR", ...) - - pattern: fmt.Sprintf("$URLSTR", ...) - - pattern: fmt.Printf("$URLSTR", ...) - - metavariable-regex: - metavariable: $URLSTR - regex: http(s?)://%(v|s|q).* - - patterns: - - pattern: '"$URLSTR" + ...' - - metavariable-regex: - metavariable: $URLSTR - regex: \w+://.* - pattern-sources: - - pattern-either: - - pattern: "($REQUEST : *http.Request).$ANYTHING" - - pattern: "($REQUEST : http.Request).$ANYTHING" - severity: WARNING diff --git a/tests/semgrep/go/lang/security/zip.yaml b/tests/semgrep/go/lang/security/zip.yaml deleted file mode 100644 index 8885bd3..0000000 --- a/tests/semgrep/go/lang/security/zip.yaml +++ /dev/null @@ -1,20 +0,0 @@ -rules: - - id: path-traversal-inside-zip-extraction - message: File traversal when extracting zip archive - metadata: - cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')" - source_rule_url: https://github.com/securego/gosec/issues/205 - category: security - technology: - - go - confidence: MEDIUM - languages: [go] - severity: WARNING - pattern: | - reader, $ERR := zip.OpenReader($ARCHIVE) - ... - for _, $FILE := range reader.File { - ... - path := filepath.Join($TARGET, $FILE.Name) - ... - } diff --git a/tests/semgrep/go/otto/security/audit/dangerous-execution.yaml b/tests/semgrep/go/otto/security/audit/dangerous-execution.yaml deleted file mode 100644 index 1dc547e..0000000 --- a/tests/semgrep/go/otto/security/audit/dangerous-execution.yaml +++ /dev/null @@ -1,24 +0,0 @@ -rules: - - id: dangerous-execution - message: >- - Detected non-static script inside otto VM. Audit the input to 'VM.Run'. - If unverified user data can reach this call site, this is a code injection - vulnerability. A malicious actor can inject a malicious script to execute - arbitrary code. - metadata: - cwe: "CWE-94: Improper Control of Generation of Code ('Code Injection')" - owasp: "A1: Injection" - category: security - technology: - - otto - - vm - confidence: MEDIUM - severity: ERROR - patterns: - - pattern-inside: | - $VM = otto.New(...) - ... - - pattern-not: $VM.Run("...", ...) - - pattern: $VM.Run(...) - languages: - - go diff --git a/tests/semgrep/go/template/security/insecure-types.yaml b/tests/semgrep/go/template/security/insecure-types.yaml deleted file mode 100644 index bc001e9..0000000 --- a/tests/semgrep/go/template/security/insecure-types.yaml +++ /dev/null @@ -1,26 +0,0 @@ -rules: - - id: go-insecure-templates - patterns: - - pattern-inside: | - import "html/template" - ... - - pattern-either: - - pattern: var $VAR template.HTML = $EXP - - pattern: var $VAR template.CSS = $EXP - - pattern: var $VAR template.HTMLAttr = $EXP - - pattern: var $VAR template.JS = $EXP - - pattern: var $VAR template.JSStr = $EXP - - pattern: var $VAR template.Srcset = $EXP - message: >- - usage of insecure template types. They are documented as a security risk. See https://golang.org/pkg/html/template/#HTML. - severity: WARNING - metadata: - references: - - https://golang.org/pkg/html/template/#HTML - - https://twitter.com/empijei/status/1275177219011350528 - category: security - technology: - - template - confidence: MEDIUM - languages: - - go From 652531f191fdc1572e250f210e427591f5c77a01 Mon Sep 17 00:00:00 2001 From: eikendev Date: Sun, 13 Feb 2022 21:07:21 +0100 Subject: [PATCH 11/17] Add configuration for GoReleaser --- .github/workflows/publish.yml | 9 +++++++++ .goreleaser.yml | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 .goreleaser.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 444e5bc..cc69713 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -58,3 +58,12 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v2 + with: + distribution: goreleaser + version: latest + args: release --rm-dist + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..144bdc2 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,19 @@ +builds: + - id: pushbits + main: ./cmd/pushbits + goos: + - linux + goarch: + - amd64 + - 386 + - arm + - arm64 + +checksum: + algorithm: sha256 + +archives: + - id: pushbits + builds: + - pushbits + format: tar.gz From ab6cf65244b2b5c002f55b2f9e708d3dd6bd7a45 Mon Sep 17 00:00:00 2001 From: eikendev Date: Mon, 14 Feb 2022 20:51:57 +0100 Subject: [PATCH 12/17] Exclude tests when generating API docs --- Makefile | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index fbecf5d..520967c 100644 --- a/Makefile +++ b/Makefile @@ -1,20 +1,26 @@ -OUTDIR := ./out +# References: +# [1] Needed so the Go files of semgrep-rules do not interfere with static analysis -SEMGREP_MODFILE := ./tests/semgrep-rules/go.mod +DOCS_DIR := ./docs +OUT_DIR := ./out +TESTS_DIR := ./tests + +SEMGREP_MODFILE := $(TESTS_DIR)/semgrep-rules/go.mod .PHONY: build build: - mkdir -p $(OUTDIR) - go build -ldflags="-w -s" -o $(OUTDIR)/pushbits ./cmd/pushbits + mkdir -p $(OUT_DIR) + go build -ldflags="-w -s" -o $(OUT_DIR)/pushbits ./cmd/pushbits .PHONY: clean clean: - rm -rf $(OUTDIR) + rm -rf $(DOCS_DIR) + rm -rf $(OUT_DIR) rm -rf $(SEMGREP_MODFILE) .PHONY: test test: - touch $(SEMGREP_MODFILE) # Needed so the Go files of semgrep-rules do not interfere with static analysis + touch $(SEMGREP_MODFILE) # See [1]. go fmt ./... go vet ./... gocyclo -over 10 $(shell find . -type f \( -iname '*.go' ! -path "./tests/semgrep-rules/*" \)) @@ -22,7 +28,7 @@ test: go test -v -cover ./... gosec -exclude-dir=tests ./... semgrep --lang=go --config=tests/semgrep-rules/go --metrics=off - rm -rf $(SEMGREP_MODFILE) + rm -rf $(SEMGREP_MODFILE) # See [1]. @printf '\n%s\n' "> Test successful" .PHONY: setup @@ -36,4 +42,4 @@ setup: .PHONY: swag swag: - swag init --parseDependency=true -d . -g cmd/pushbits/main.go + swag init --parseDependency=true --exclude $(TESTS_DIR) -g cmd/pushbits/main.go From 23f457a5950966d548005e32f90f89e7f36e8916 Mon Sep 17 00:00:00 2001 From: eikendev Date: Tue, 15 Feb 2022 13:18:58 +0100 Subject: [PATCH 13/17] Link to contribution guidelines --- README.md | 13 +++++++++---- SECURITY.md | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e08a4c6..f9387bf 100644 --- a/README.md +++ b/README.md @@ -64,13 +64,18 @@ It applies only where not specified differently. The idea for this software was inspired by [Gotify](https://gotify.net/). -## 💻 Development +## 💻 Development and Contributions The source code is located on [GitHub](https://github.com/pushbits/server). -You can retrieve it by checking out the repository as follows. - +You can retrieve it by checking out the repository as follows: ```bash git clone https://github.com/pushbits/server.git ``` -Check out [the stargazers over time](https://starchart.cc/pushbits/server) for a fancy graph. +:computer: **Want to contribute?** +Before moving forward, please refer to [out contribution guidelines](CONTRIBUTING.md). + +:mailbox: **Found a security vulnerability?** +Check [this document](SECURITY.md) for information on how you can bring it to our attention. + +:star: **Like fancy graphs?** See [our stargazers over time](https://starchart.cc/pushbits/server). diff --git a/SECURITY.md b/SECURITY.md index 22ef60a..2d399ac 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,7 +2,7 @@ ## Supported Versions -Only the latest version is supported. +Because we are a small team, only the latest version is supported. ## Reporting a Vulnerability From 5930b85b39521eab6d9726ff02cced2ae355b0fb Mon Sep 17 00:00:00 2001 From: eikendev Date: Tue, 15 Feb 2022 13:22:41 +0100 Subject: [PATCH 14/17] Replace emoji in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f9387bf..1dc21fb 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ You can retrieve it by checking out the repository as follows: git clone https://github.com/pushbits/server.git ``` -:computer: **Want to contribute?** +:wrench: **Want to contribute?** Before moving forward, please refer to [out contribution guidelines](CONTRIBUTING.md). :mailbox: **Found a security vulnerability?** From 9a7a07a82478e191581912ce370e54e43985b635 Mon Sep 17 00:00:00 2001 From: eikendev Date: Tue, 15 Feb 2022 22:40:40 +0100 Subject: [PATCH 15/17] Move FAQ to the bottom --- README.md | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 1dc21fb..63a9e66 100644 --- a/README.md +++ b/README.md @@ -31,21 +31,7 @@ It enables you to send notifications via a simple web API, and delivers them to This is similar to what [Pushover](https://pushover.net/) and [Gotify](https://gotify.net/) offer, but it does not require an additional app. The vision is to have compatibility with Gotify on the sending side, while on the receiving side an established service is used. -This has the advantages that -- sending plugins written for Gotify (like those for [Watchtower](https://containrrr.dev/watchtower/) and [Jellyfin](https://jellyfin.org/)) as well as -- receiving clients written for Matrix -can be reused. - -### Why Matrix instead of X? - -This project totally would've used Signal if it would offer a proper API. -Sadly, neither [Signal](https://signal.org/) nor [WhatsApp](https://www.whatsapp.com/) come with an API (at the time of writing) through which PushBits could interact. - -In [Telegram](https://telegram.org/) there is an API to run bots, but these are limited in that they cannot create chats by themselves. -If you insist on going with Telegram, have a look at [webhook2telegram](https://github.com/muety/webhook2telegram). - -The idea of a federated, synchronized but yet end-to-end encrypted protocol is awesome, but its clients simply aren't really there yet. -Still, if you haven't tried it yet, we'd encourage you to check it out. +This has the advantages that we need to maintain neither plugins (like those for [Watchtower](https://containrrr.dev/watchtower/) and [Jellyfin](https://jellyfin.org/)) nor clients. ## 🤘 Features @@ -79,3 +65,16 @@ Before moving forward, please refer to [out contribution guidelines](CONTRIBUTIN Check [this document](SECURITY.md) for information on how you can bring it to our attention. :star: **Like fancy graphs?** See [our stargazers over time](https://starchart.cc/pushbits/server). + +## ❓ Frequently Asked Questions (FAQ) + +### Why Matrix instead of X? + +This project totally would've used Signal if it would offer a proper API. +Sadly, neither [Signal](https://signal.org/) nor [WhatsApp](https://www.whatsapp.com/) come with an API (at the time of writing) through which PushBits could interact. + +In [Telegram](https://telegram.org/) there is an API to run bots, but these are limited in that they cannot create chats by themselves. +If you insist on going with Telegram, have a look at [webhook2telegram](https://github.com/muety/webhook2telegram). + +The idea of a federated, synchronized but yet end-to-end encrypted protocol is awesome, but its clients simply aren't really there yet. +Still, if you haven't tried it yet, we'd encourage you to check it out. From de18aa9ade9c06f251ac2d5be989882c133f2a30 Mon Sep 17 00:00:00 2001 From: eikendev Date: Tue, 15 Feb 2022 22:43:49 +0100 Subject: [PATCH 16/17] Correct spelling in README.md --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 63a9e66..631755e 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,7 @@

PushBits

-

- Receive your important notifications immediately, over Matrix. -

+

Receive your important notifications immediately, over Matrix.

PushBits enables you to send push notifications via a simple web API, and delivers them to your users.

@@ -52,14 +50,14 @@ The idea for this software was inspired by [Gotify](https://gotify.net/). ## 💻 Development and Contributions -The source code is located on [GitHub](https://github.com/pushbits/server). +The source code is located [on GitHub](https://github.com/pushbits/server). You can retrieve it by checking out the repository as follows: ```bash git clone https://github.com/pushbits/server.git ``` :wrench: **Want to contribute?** -Before moving forward, please refer to [out contribution guidelines](CONTRIBUTING.md). +Before moving forward, please refer to [our contribution guidelines](CONTRIBUTING.md). :mailbox: **Found a security vulnerability?** Check [this document](SECURITY.md) for information on how you can bring it to our attention. From 37b20fd5568812ddb005543315219b8a09ecb488 Mon Sep 17 00:00:00 2001 From: eikendev Date: Tue, 15 Feb 2022 22:45:03 +0100 Subject: [PATCH 17/17] Bold subtitle in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 631755e..b38cd80 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@

PushBits

-

Receive your important notifications immediately, over Matrix.

+

Receive your important notifications immediately, over Matrix.

PushBits enables you to send push notifications via a simple web API, and delivers them to your users.