python.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:
- python
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-sinks:
- patterns:
- pattern-either:
- pattern: |
"$SQLSTR" + ...
- pattern: |
"$SQLSTR" % ...
- pattern: |
"$SQLSTR".format(...)
- pattern: |
f"$SQLSTR{...}..."
- metavariable-regex:
metavariable: $SQLSTR
regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.*=
- pattern-not-inside: |
print(...)
pattern-sources:
- patterns:
- pattern: event
- pattern-inside: |
def $HANDLER(event, context):
...
severity: ERROR
Examples
tainted-sql-string.py
import json
import secret_info
import mysql.connector
RemoteMysql = secret_info.RemoteMysql
mydb = mysql.connector.connect(host=RemoteMysql.host, user=RemoteMysql.user, passwd=RemoteMysql.passwd, database=RemoteMysql.database)
mydbCursor = mydb.cursor()
def lambda_handler(event, context):
publicIP=event["queryStringParameters"]["publicIP"]
# ruleid: tainted-sql-string
sql = """UPDATE `EC2ServerPublicIP` SET %s = '%s' WHERE %s = %d""" % ("publicIP",publicIP,"ID", 1)
# ok: tainted-sql-string
print("""UPDATE `EC2ServerPublicIP` SET %s = '%s' WHERE %s = %d""" % ("publicIP",publicIP,"ID", 1))
mydbCursor.execute(sql)
# ok: tainted-sql-string
sql2 = "UPDATE `EC2ServerPublicIP` SET %s = '%s' WHERE foo = %s" % ("one", "two", "three")
# ok: tainted-sql-string
mydbCursor.execute("UPDATE `EC2ServerPublicIP` SET %s = '%s' WHERE %s = %s", ("publicIP",publicIP,"ID", 1))
# ok: tainted-sql-string
sql3 = "UPDATE `EC2ServerPublicIP` SET %s = '%s'" + " WHERE %s = %s"
mydbCursor.execute(sql3, ("publicIP",publicIP,"ID", 1))
mydb.commit()
Body={
"publicIP":publicIP
}
return {
'statusCode': 200,
'body': json.dumps(Body)
}
Short Link: https://sg.run/wXvA