go.gorm.security.audit.gorm-dangerous-methods-usage.gorm-dangerous-method-usage

Author
unknown
Download Count*
License
Detected usage of dangerous method $METHOD which does not escape inputs (see link in references). If the argument is user-controlled, this can lead to SQL injection. When using $METHOD function, do not trust user-submitted data and only allow approved list of input (possibly, use an allowlist approach).
Run Locally
Run in CI
Defintion
rules:
- id: gorm-dangerous-method-usage
message: Detected usage of dangerous method $METHOD which does not escape inputs
(see link in references). If the argument is user-controlled, this can
lead to SQL injection. When using $METHOD function, do not trust
user-submitted data and only allow approved list of input (possibly, use
an allowlist approach).
severity: WARNING
languages:
- go
mode: taint
pattern-sources:
- patterns:
- pattern-either:
- pattern: |
($REQUEST : http.Request).$ANYTHING
- pattern: |
($REQUEST : *http.Request).$ANYTHING
- metavariable-regex:
metavariable: $ANYTHING
regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$
pattern-sinks:
- patterns:
- pattern-inside: |
import ("gorm.io/gorm")
...
- patterns:
- pattern-inside: |
func $VAL(..., $GORM *gorm.DB,... ) {
...
}
- pattern-either:
- pattern: |
$GORM. ... .$METHOD($VALUE)
- pattern: |
$DB := $GORM. ... .$ANYTHING(...)
...
$DB. ... .$METHOD($VALUE)
- focus-metavariable: $VALUE
- metavariable-regex:
metavariable: $METHOD
regex: ^(Order|Exec|Raw|Group|Having|Distinct|Select|Pluck)$
metadata:
category: security
technology:
- gorm
cwe:
- "CWE-89: Improper Neutralization of Special Elements used in an SQL
Command ('SQL Injection')"
owasp:
- A01:2017 - Injection
- A03:2021 - Injection
references:
- https://gorm.io/docs/security.html#SQL-injection-Methods
- https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
confidence: MEDIUM
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- vuln
likelihood: HIGH
impact: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
Examples
gorm-dangerous-methods-usage.go
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type User struct {
gorm.Model
FirstName string
LastName string
Email string `gorm:"unique_index:user_email_index"`
Password string
Token string
TokenExpiresAt uint
}
func testInjection(w http.ResponseWriter, r *http.Request, db *gorm.DB) {
param := r.Cookie("foo")
if param != "" {
table := db.Table("users")
var u User
//ruleid: gorm-dangerous-method-usage
table.Order(param).Find(&u)
}
}
func testInjection2(w http.ResponseWriter, r *http.Request, db *gorm.DB) {
param := r.URL.Query().Get("orderBy")
if param != "" {
table := db.Table("users")
var u User
//ruleid: gorm-dangerous-method-usage
table.Order(param + " " + "ASC").Find(&u)
}
}
func testNoInjection(w http.ResponseWriter, r *http.Request, db *gorm.DB) {
table := db.Table("users")
var u User
//ok: gorm-dangerous-method-usage
table.Order("email").Find(&u)
}
func testNoInjection2(w http.ResponseWriter, r *http.Request, db *gorm.DB) {
table := db.Table("users")
var orderBy = "email"
var u User
//ok: gorm-dangerous-method-usage
table.Order(orderBy).Find(&u)
}
func main() {
dsn := "dbuser:password@tcp(127.0.0.1:3306)/users?charset=utf8&parseTime=True"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
fmt.Println(err)
}
db.AutoMigrate(&User{})
myRouter := mux.NewRouter().StrictSlash(true)
myRouter.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
testInjection(w, r, db)
}).Methods("GET")
http.ListenAndServe(":10000", myRouter)
}
Short Link: https://sg.run/R4qg