go.aws-lambda.security.tainted-sql-string.tainted-sql-string

Author
unknown
Download Count*
License
Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries.
Run Locally
Run in CI
Defintion
rules:
- id: tainted-sql-string
languages:
- go
severity: ERROR
message: Detected user input used to manually construct a SQL string. This is
usually bad practice because manual construction could accidentally result
in a SQL injection. An attacker could use a SQL injection to steal or
modify contents of the database. Instead, use a parameterized query which
is available by default in most database engines. Alternatively, consider
using an object-relational mapper (ORM) such as Sequelize which will
protect your queries.
metadata:
references:
- https://owasp.org/www-community/attacks/SQL_Injection
category: security
owasp:
- A01:2017 - Injection
- A03:2021 - Injection
cwe:
- "CWE-89: Improper Neutralization of Special Elements used in an SQL
Command ('SQL Injection')"
technology:
- aws-lambda
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- vuln
likelihood: HIGH
impact: MEDIUM
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
mode: taint
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, ...)
- focus-metavariable: $EVENT
pattern-sinks:
- patterns:
- pattern-either:
- patterns:
- pattern: |
"$SQLSTR" + ...
- metavariable-regex:
metavariable: $SQLSTR
regex: (?i)(\s*select|\s*delete|\s*insert|\s*create|\s*update|\s*alter|\s*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-not-inside: |
log.$PRINT(...)
pattern-sanitizers:
- pattern: strconv.Atoi(...)
Examples
tainted-sql-string.go
package main
import (
"database/sql"
"encoding/json"
"log"
"os"
"strconv"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
_ "github.com/go-sql-driver/mysql"
)
var (
db *sql.DB
err error
connectionString string
dbUser string
dbPass string
dataSource string
)
type Employee struct {
EmployeeNo int `json:"emp_no"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
}
func init() {
connectionString = os.Getenv("CONN")
dbUser = os.Getenv("DBUSER")
dbPass = os.Getenv("DBPASS")
dataSource = dbUser + ":" + dbPass + "@tcp(" + connectionString + ")/employees"
}
func handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
searchCriteria := request.Body
db, err = sql.Open("mysql", dataSource)
if err != nil {
panic(err.Error())
}
defer db.Close()
// ruleid: tainted-sql-string
results, err := db.Query("select e.emp_no, e.first_name, e.last_name " +
"from employees e, departments d, dept_emp de " +
"where e.last_name LIKE '" + searchCriteria + "%';")
if err != nil {
log.Fatal(err)
}
defer results.Close()
// ruleid: tainted-sql-string
_, err = db.Exec(`
DELETE FROM table WHERE Id = ` + request.Get("Id"))
// ruleid: tainted-sql-string
_, err = db.Exec("DELETE FROM table WHERE Id = " + request.Get("Id"))
// ok: tainted-sql-string
log.Printf("DELETE FROM table WHERE Id = " + request.Get("Id"))
// ok: tainted-sql-string
_, err = db.Exec(` FAKE
DELETE FROM table WHERE Id = ` + request.Get("Id"))
idhtml := request.Get("Id")
id, _ := strconv.Atoi(idhtml)
// ok: tainted-sql-string
_, err = db.Exec("DELETE FROM table WHERE Id = " + id)
// ok: tainted-sql-string
results2, err2 := db.Query("select * from foobar")
employees := make([]Employee, 0)
for results.Next() {
var e Employee
err := results.Scan(&e.EmployeeNo, &e.FirstName, &e.LastName)
if err != nil {
log.Fatal(err)
}
employees = append(employees, e)
}
data, _ := json.Marshal(employees)
return events.APIGatewayProxyResponse{
StatusCode: 200,
Body: string(data),
IsBase64Encoded: false,
}, nil
}
func main() {
lambda.Start(handler)
}
Short Link: https://sg.run/vX3Y