include::../description.adoc[]

include::../ask-yourself.adoc[]

include::../recommended.adoc[]

== Sensitive Code Example

----
$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;
}
----

== Compliant Solution

[source,php]
----
$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();
}
----

== Exceptions

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
----

include::../see.adoc[]

ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

include::../message.adoc[]

include::../highlighting.adoc[]

'''
== Comments And Links
(visible only on this page)

=== on 27 Jul 2015, 12:37:52 Ann Campbell wrote:
Ref: \http://code.tutsplus.com/tutorials/php-database-access-are-you-doing-it-correctly--net-25338

=== on 27 Jul 2015, 12:38:13 Ann Campbell wrote:
back to you for double-checking [~alexandre.gigleux]

=== on 1 Sep 2016, 14:48:21 Alexandre Gigleux wrote:
LGTM

=== on 22 Oct 2018, 13:30:30 Nicolas Harraudeau wrote:
*Implementation details*:

The functions listed above don't support prepared statements, thus the only way to provide parameters is to concatenate strings. An issue will be created if it cannot be proven that the SQL string is hardcoded. For example an issue will be created if the SQL string is provided as a variable to the current method. If on the contrary the variable is local to the method and is assigned a hard-coded string there will be no issue raised.


For other functions which support prepared statement, the default behavior should be inverted. If the string cannot be proven to be concatenated there is no issue. Thus no issue will be created if the SQL string is provided as a variable to the current method.

include::../comments-and-links.adoc[]

endif::env-github,rspecator-view[]
