From 7dc51773ab664dde3d40d989962bda7b4ef376f6 Mon Sep 17 00:00:00 2001 From: Terra Date: Mon, 28 Dec 2020 19:37:09 +1100 Subject: [PATCH] some fixes Signed-off-by: Terra --- api/bans/get/index.php | 57 +++++++++++++++++++++++------------------- api/utils.php | 24 ++++++++++++++++++ schema_api.sql | 2 +- 3 files changed, 56 insertions(+), 27 deletions(-) diff --git a/api/bans/get/index.php b/api/bans/get/index.php index cfbafbd..747e5e5 100644 --- a/api/bans/get/index.php +++ b/api/bans/get/index.php @@ -16,10 +16,14 @@ return; } +// Because I can't specify the sort order with prepared statements, I need to sanitize the order param, on the off chance that someone manages to compromize the server AND get the API key AND make a valid request +$saniOrder = sql_escape("`{$_GET['sort']}` {$_GET['order']}"); // Var to store number of bans selected $totalBans = 0; // Universal var to store our results to. We can avoid some copypasta with this. $rows = array(); +// Do some stuff with the IP address + // Handle each different type of search if(key_exists('all', $_GET['search'])) { @@ -34,20 +38,19 @@ $term, $term, $term, - $term + ip_to_int($term), ]); // Now through the power of copypasta, get required amount of rows, god it's so ugly - $rows = sql_query("SELECT * FROM `bans` WHERE `removed` = ? AND (`ckey` LIKE CONCAT('%', ?, '%') OR `akey` LIKE CONCAT('%', ?, '%') OR `reason` LIKE CONCAT('%', ?, '%') OR `compid` = ? OR `ip` = ?) ORDER BY ? LIMIT ? OFFSET ?", + $rows = sql_query("SELECT * FROM `bans` WHERE `removed` = ? AND (`ckey` LIKE CONCAT('%', ?, '%') OR `akey` LIKE CONCAT('%', ?, '%') OR `reason` LIKE CONCAT('%', ?, '%') OR `compid` = ? OR `ip` = ?) ORDER BY {$saniOrder} LIMIT ? OFFSET ?", [ - 'issssisii', + 'issssiii', $_GET['removed'], $term, $term, $term, $term, - $term, - strtolower($_GET['order']), + ip_to_int($term), $_GET['limit'], $_GET['offset'] ], true); @@ -56,31 +59,31 @@ $totalBans = sql_query("SELECT * FROM `bans` WHERE `removed` = ? AND `ckey` LIKE CONCAT('%', ?, '%')", ['is', $_GET['removed'], $term]); - $rows = sql_query("SELECT * FROM `bans` WHERE `removed` = ? AND `ckey` LIKE CONCAT('%', ?, '%') ORDER BY ? LIMIT ? OFFSET ?", ['isii', $_GET['removed'], $term, strtolower($_GET['order']), $_GET['limit'], $_GET['offset']], true); + $rows = sql_query("SELECT * FROM `bans` WHERE `removed` = ? AND `ckey` LIKE CONCAT('%', ?, '%') ORDER BY {$saniOrder} LIMIT ? OFFSET ?", ['isii', $_GET['removed'], $term, $_GET['limit'], $_GET['offset']], true); } elseif(key_exists('akey', $_GET['search'])) { $term = $_GET['search']['akey']; $totalBans = sql_query("SELECT * FROM `bans` WHERE `removed` = ? AND `akey` LIKE CONCAT('%', ?, '%')", ['is', $_GET['removed'], $term]); - $rows = sql_query("SELECT * FROM `bans` WHERE `removed` = ? AND `akey` LIKE CONCAT('%', ?, '%') ORDER BY ? LIMIT ? OFFSET ?", ['isii', $_GET['removed'], $term, strtolower($_GET['order']), $_GET['limit'], $_GET['offset']], true); + $rows = sql_query("SELECT * FROM `bans` WHERE `removed` = ? AND `akey` LIKE CONCAT('%', ?, '%') ORDER BY {$saniOrder} LIMIT ? OFFSET ?", ['isii', $_GET['removed'], $term, $_GET['limit'], $_GET['offset']], true); } elseif(key_exists('reason', $_GET['search'])) { $term = $_GET['search']['reason']; $totalBans = sql_query("SELECT * FROM `bans` WHERE `removed` = ? AND `reason` LIKE CONCAT('%', ?, '%')", ['is', $_GET['removed'], $term]); - $rows = sql_query("SELECT * FROM `bans` WHERE `removed` = ? AND `reason` LIKE CONCAT('%', ?, '%') ORDER BY ? LIMIT ? OFFSET ?", ['isii', $_GET['removed'], $term, strtolower($_GET['order']), $_GET['limit'], $_GET['offset']], true); + $rows = sql_query("SELECT * FROM `bans` WHERE `removed` = ? AND `reason` LIKE CONCAT('%', ?, '%') ORDER BY {$saniOrder} LIMIT ? OFFSET ?", ['isii', $_GET['removed'], $term, $_GET['limit'], $_GET['offset']], true); } elseif(key_exists('compID', $_GET['search'])) { $term = $_GET['search']['compID']; $totalBans = sql_query("SELECT * FROM `bans` WHERE `removed` = ? AND `compid` = ?", ['is', $_GET['removed'], $term]); - $rows = sql_query("SELECT * FROM `bans` WHERE `removed` = ? AND `compid` = ? ORDER BY ? LIMIT ? OFFSET ?", ['isii', $_GET['removed'], $term, strtolower($_GET['order']), $_GET['limit'], $_GET['offset']], true); + $rows = sql_query("SELECT * FROM `bans` WHERE `removed` = ? AND `compid` = ? ORDER BY {$saniOrder} LIMIT ? OFFSET ?", ['isii', $_GET['removed'], $term, $_GET['limit'], $_GET['offset']], true); } elseif(key_exists('ip', $_GET['search'])) { $term = $_GET['search']['ip']; $totalBans = sql_query("SELECT * FROM `bans` WHERE `removed` = ? AND `ip` = ?", ['ii', $_GET['removed'], ip_to_int($term)]); - $rows = sql_query("SELECT * FROM `bans` WHERE `removed` = ? AND `ip` = ? ORDER BY ? LIMIT ? OFFSET ?", ['iiii', $_GET['removed'], ip_to_int($term), strtolower($_GET['order']), $_GET['limit'], $_GET['offset']], true); + $rows = sql_query("SELECT * FROM `bans` WHERE `removed` = ? AND `ip` = ? ORDER BY {$saniOrder} LIMIT ? OFFSET ?", ['iiii', $_GET['removed'], ip_to_int($term), $_GET['limit'], $_GET['offset']], true); } else { // wut echo json_error("No valid search term provided"); @@ -91,22 +94,24 @@ $response = array(); $response['total'] = $totalBans; -foreach($rows as $row) { - $response[$row['id']] = [ - 'id' => $row['id'], - 'ckey' => $row['ckey'], - 'compID' => $row['compid'], - 'ip' => int_to_ip($row['ip']), - 'reason' => $row['reason'], - 'timestamp' => $row['timestamp'], - 'akey' => $row['akey'], - 'oakey' => $row['oakey'], - 'previous' => $row['previous'], - 'chain' => $row['chain'] - ]; - - if($row['server']) { - $response[$row['id']]['server'] = $row['server']; +if($rows) { + foreach($rows as $row) { + $response[$row['id']] = [ + 'id' => $row['id'], + 'ckey' => $row['ckey'], + 'compID' => $row['compid'], + 'ip' => int_to_ip($row['ip']), + 'reason' => $row['reason'], + 'timestamp' => $row['timestamp'], + 'akey' => $row['akey'], + 'oakey' => $row['oakey'], + 'previous' => $row['previous'], + 'chain' => $row['chain'] + ]; + + if($row['server']) { + $response[$row['id']]['server'] = $row['server']; + } } } diff --git a/api/utils.php b/api/utils.php index 6f19fe9..93bf811 100644 --- a/api/utils.php +++ b/api/utils.php @@ -100,6 +100,16 @@ function sql_query($query, $params, $returnValues = false, $failSafe = false) { return $result; } +// Connects to the DB and escapes a string for (probably) safe use. +function sql_escape($str) { + global $databaseAddress, $databaseUser, $databasePassword, $databaseName; + mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); + $db = mysqli_connect($databaseAddress, $databaseUser, $databasePassword, $databaseName); + $out = $db->real_escape_string($str); + $db->close(); + return $out; +} + // Referenceize arrays for arg passing function ref_values($arr){ if (strnatcmp(phpversion(),'5.3') >= 0) //Reference is required for PHP 5.3+ @@ -113,11 +123,25 @@ function ref_values($arr){ } function ip_to_int($ipStr) { + if($ipStr == "N/A") { + return 0; + } $arr = preg_split('/\./', $ipStr); + if(count($arr) != 4) { + return -1; + } + foreach($arr as $val) { + if(!is_numeric($val)) { + return -1; + } + } return ((int)$arr[0] * (256 ** 3)) + ((int)$arr[1] * (256 ** 2)) + ((int)$arr[2] * 256) + ((int)$arr[3]); } function int_to_ip($ipInt) { + if($ipInt == 0) { + return "N/A"; + } $one = $ipInt & 255; $two = ($ipInt & 65280) >> 8; $three = ($ipInt & 16711680) >> 16; diff --git a/schema_api.sql b/schema_api.sql index eacd750..e59ce73 100644 --- a/schema_api.sql +++ b/schema_api.sql @@ -91,7 +91,7 @@ CREATE TABLE IF NOT EXISTS `bans` ( `previous` INT UNSIGNED NOT NULL DEFAULT '0', `chain` SMALLINT UNSIGNED NOT NULL DEFAULT '0', `server` VARCHAR(32) DEFAULT NULL, - `removed` BOOLEAN NOT NULL DEFAULT 'FALSE', -- tbh, we shouldn't just nuke bans from the face of the earth, because that's what I did. let's keep them around for admins to look at + `removed` BOOLEAN NOT NULL DEFAULT FALSE, -- tbh, we shouldn't just nuke bans from the face of the earth, because that's what I did. let's keep them around for admins to look at PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;