Formatting strings used as SQL queries is security-sensitive. It has led in the past to the following vulnerabilities:
SQL queries often need to use a hardcoded SQL string with a dynamic parameter coming from a user request. Formatting a string to add those parameters to the request is a bad practice as it can result in an SQL injection. The safe way to add parameters to a SQL query is to use SQL binding mechanisms.
This rule flags the execution of SQL queries which are built using formatting of strings, even if there is no injection. This rule does not detect SQL injections. The goal is to guide security code reviews and to prevent a common bad practice.
The following functions are detected as SQL query execution:
mysql_query mysql_db_query mysql_unbuffered_query pg_query pg_send_query mssql_query mysqli_query and mysqli::query mysqli_real_query and mysqli::real_query mysqli_multi_query and mysqli::multi_query mysqli_send_query and mysqli::send_query PDO::query PDO::exec PDO::prepare You may be at risk if you answered yes to this question.
You can also reduce the impact of an attack by using a database account with low privileges.
$id = $_GET['id'];
mysql_connect('localhost', $username, $password) or die('Could not connect: ' . mysql_error());
mysql_select_db('myDatabase') or die('Could not select database');
$result = mysql_query("SELECT * FROM myTable WHERE id = " . $id); // Sensitive, could be susceptible to SQL injection
while ($row = mysql_fetch_object($result)) {
echo $row->name;
}
$id = $_GET['id'];
try {
$conn = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $conn->prepare('SELECT * FROM myTable WHERE id = :id');
$stmt->execute(array('id' => $id));
while($row = $stmt->fetch(PDO::FETCH_OBJ)) {
echo $row->name;
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
No issue will be raised if one of the functions is called with hard-coded string (no concatenation) and this string does not contain a "$" sign.
$result = mysql_query("SELECT * FROM myTable WHERE id = 42") or die('Query failed: ' . mysql_error()); // Compliant
The current implementation does not follow variables. It will only detect SQL queries which are concatenated or contain a $ sign
directly in the function call.
$query = "SELECT * FROM myTable WHERE id = " . $id; $result = mysql_query($query); // No issue will be raised even if it is Sensitive