php.lang.security.injection.tainted-sql-string.tainted-sql-string

Author
unknown
Download Count*
License
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 ($mysqli->prepare("INSERT INTO test(id, label) VALUES (?, ?)");
) or a safe library.
Run Locally
Run in CI
Defintion
rules:
- id: tainted-sql-string
languages:
- php
severity: ERROR
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
(`$mysqli->prepare("INSERT INTO test(id, label) VALUES (?, ?)");`) or a
safe library.
metadata:
cwe:
- "CWE-89: Improper Neutralization of Special Elements used in an SQL
Command ('SQL Injection')"
owasp:
- A01:2017 - Injection
- A03:2021 - Injection
references:
- https://owasp.org/www-community/attacks/SQL_Injection
category: security
technology:
- php
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-sanitizers:
- pattern-either:
- pattern: mysqli_real_escape_string(...)
- pattern: real_escape_string(...)
- pattern: $MYSQLI->real_escape_string(...)
pattern-sources:
- patterns:
- pattern-either:
- pattern: $_GET
- pattern: $_POST
- pattern: $_COOKIE
- pattern: $_REQUEST
pattern-sinks:
- pattern-either:
- patterns:
- pattern: |
sprintf($SQLSTR, ...)
- metavariable-regex:
metavariable: $SQLSTR
regex: .*\b(?i)(select|delete|insert|create|update|alter|drop)\b.*
- patterns:
- pattern: |
"...{$EXPR}..."
- pattern-regex: |
.*\b(?i)(select|delete|insert|create|update|alter|drop)\b.*
- patterns:
- pattern: |
"...$EXPR..."
- pattern-regex: |
.*\b(?i)(select|delete|insert|create|update|alter|drop)\b.*
- patterns:
- pattern: |
"...".$EXPR
- pattern-regex: |
.*\b(?i)(select|delete|insert|create|update|alter|drop)\b.*
Examples
tainted-sql-string.php
<?php
// True Positives
function test1() {
// ruleid: tainted-sql-string
$query = "SELECT * FROM table WHERE Id = '".$_GET['url']."'";
$info = mysql_query($query);
return $info;
}
function test2() {
$part = $_POST['url'];
// ruleid: tainted-sql-string
$query = "SELECT * FROM table WHERE Id = '$part'";
$info = mysql_query($query);
return $info;
}
function test3() {
// ruleid: tainted-sql-string
$query = "SELECT * FROM table WHERE Id = '{$_REQUEST['url']}'";
$info = mysql_query($query);
return $info;
}
function test4() {
// ruleid: tainted-sql-string
$query = sprintf("SELECT * FROM table WHERE Id = '%s'", $_COOKIE['foo']);
$info = mysql_query($query);
return $info;
}
// True Negatives
function test1() {
// ok: tainted-sql-string
$query = 'SELECT * FROM table WHERE Id = 1';
$info = mysql_query($query);
return $info;
}
function test2() {
$value = 1;
// ok: tainted-sql-string
$query = "SELECT * FROM table WHERE Id = '".$value."'";
$info = mysql_query($query);
return $info;
}
function test3() {
// ok: tainted-sql-string
$query = "SELECT * FROM table WHERE Id = '{$foobar() ? 1 : 2}'";
$info = mysql_query($query);
return $info;
}
function test4() {
$value = 1;
// ok: tainted-sql-string
$query = sprintf("SELECT * FROM table WHERE Id = '%s'", $value);
$info = mysql_query($query);
return $info;
}
function test5() {
$part = $_POST['url'];
$part = mysqli_real_escape_string($part);
// ok: tainted-sql-string
$query = sprintf("SELECT * FROM table WHERE Id = '" . $part . "'");
$info = mysql_query($query);
return $info;
}
Short Link: https://sg.run/lZYG