Prevent unlimited mysqli queries

I work for a company that uses this Mysqli php class to make mysql calls . The problem is that the previous programmer was not great at preventing unlimited requests. So in the whole code there are things similar to the following:

$db -> where('id',$_POST['id']);
$db -> delete('table');

This code should delete only one entry, where id = $_POST['id']. However, if $_POST['id']empty, we have problems. Then it deletes the whole table. One solution to this problem would be to find all the places in the code where the delete or update functions are called, and then make sure that the where variable is actually set.

if(isset($_POST['id']) && $_POST['id']!=''){
  $db -> where('id',$_POST['id']);
  $db -> delete('table');
}

But it will take a lot of work because I know that there are about 200 instances in the code. I hope there may be a way to change the following 2 functions in order to prevent them from executing unrelated requests in the first place. Any help is appreciated!

/**
 * Update query. Be sure to first call the "where" method.
 *
 * @param string $tableName The name of the database table to work with.
 * @param array  $tableData Array of data to update the desired row.
 *
 * @return boolean
 */
public function update($tableName, $tableData)
{
    if ($this->isSubQuery)
        return;

    $this->_query = "UPDATE " . self::$_prefix . $tableName ." SET ";

    $stmt = $this->_buildQuery (null, $tableData);
    $status = $stmt->execute();
    $this->reset();
    $this->_stmtError = $stmt->error;
    $this->count = $stmt->affected_rows;

    return $status;
}

/**
 * Delete query. Call the "where" method first.
 *
 * @param string  $tableName The name of the database table to work with.
 * @param integer $numRows   The number of rows to delete.
 *
 * @return boolean Indicates success. 0 or 1.
 */
public function delete($tableName, $numRows = null)
{
    if ($this->isSubQuery)
        return;

    $this->_query = "DELETE FROM " . self::$_prefix . $tableName;

    $stmt = $this->_buildQuery($numRows);
    $stmt->execute();
    $this->_stmtError = $stmt->error;
    $this->reset();

    return ($stmt->affected_rows > 0);
}

public function where($whereProp, $whereValue = 'DBNULL', $operator = '=', $cond = 'AND')
{
    // forkaround for an old operation api
    if (is_array($whereValue) && ($key = key($whereValue)) != "0") {
        $operator = $key;
        $whereValue = $whereValue[$key];
    }
    if (count($this->_where) == 0) {
        $cond = '';
    }
    $this->_where[] = array($cond, $whereProp, $operator, $whereValue);
    return $this;
}
+4
source share
3 answers

You should catch a bad value when it is passed to the function where, not later. Thus, it is easier to track stack traces.

public function where($whereProp, $whereValue = 'DBNULL', $operator = '=', $cond = 'AND')
{
    if (is_null($whereValue) || trim($whereValue) == '') {
        throw new Exception('Cannot pass null or empty string as a condition to MysqliDb::where')
    }
    // ...
}

You can also check the array of properties _whereinside the function delete, but it is not a good practice to silently infer a method by doing a simple returnfunction. If you insist though:

public function delete($tableName, $numRows = null)
{
    foreach ($this->_where as $w) {
        if (is_null($w[3]) || trim($w[3]) == '') {
            return;
            // or alternatively throw new Exception('...')
        }
    }
    // ...
}
0
source

How about returning if this (where clause) is empty?

https://github.com/joshcam/PHP-MySQLi-Database-Class/blob/b3754d20bcebf07d65d552b2257696539a1cb144/MysqliDb.php#L1074

if (count($this->_where) == 0) {
        return;
    }
0

. ​​.

where ('val', unset) is not considered a single condition.

0
source

Source: https://habr.com/ru/post/1624861/


All Articles