designsecurity / progpilot

A static analysis tool for security
MIT License
331 stars 61 forks source link

Does not detect sql injection in mysqli_query when $_POST content passed to a function #62

Closed Jeremie-Kiwik closed 4 months ago

Jeremie-Kiwik commented 5 months ago

I found a case where progpilot missed a sql injection

This works:

$link = mysqli_connect();
mysqli_query($mysqli, 'SELECT * FROM a WHERE id = '.$_POST['id']);

But when this query is called in a function, no:

function test_procedural($link, $id) {
    mysqli_query($link, 'SELECT * FROM table WHERE id = '.$id);
}
$link = mysqli_connect();
test_procedural($link, $_POST['id']); // should trigger, but no

The error occurs both in the procuderal and object way. So the behavior is the same here:

function test_object($mysqli, $id) {
    $mysqli->query('SELECT * FROM table WHERE id = '.$id);
}
$mysqli = new mysqli('host', 'user', 'password', 'database');
test_object($mysqli, $_POST['id']); // should trigger, but no
$mysqli->query('SELECT * FROM table WHERE id = '.$_POST['id']); // triggers

Here is how I launched the test:

$ php8.3 progpilot_v1.1.0.phar test1.php
[]

(just to precise: the result is the same with php8.2 and 8.1)

For me, the call inside the function should trigger a sql injection, as the variable in the signature is not casted. For example, this should be OK, as we are now sure that $id is an int:


function test_procedural(mysqli $link, int $id) {
    mysqli_query($link, 'SELECT * FROM table WHERE id = '.$id);
}
eric-therond commented 4 months ago

thank you so much for your feedback it should be fixed now on master