diff --git a/CHANGELOG.md b/CHANGELOG.md index 90c89964..f0c8a57d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [Unreleased] + +### Fixed + +- fix escape SQL values + ## [2.15.6] - 2026-05-05 ### Fixed diff --git a/inc/commoninjectionlib.class.php b/inc/commoninjectionlib.class.php index 1ee5679c..154117d3 100644 --- a/inc/commoninjectionlib.class.php +++ b/inc/commoninjectionlib.class.php @@ -27,6 +27,8 @@ * @link https://github.com/pluginsGLPI/datainjection * ------------------------------------------------------------------------- */ + +use Glpi\DBAL\QuerySubQuery; use Glpi\Exception\Http\HttpException; use Glpi\Features\AssignableItem; @@ -1865,7 +1867,6 @@ private function dataAlreadyInDB($injectionClass, $itemtype) /** @var DBmysql $DB */ global $DB; - $where = ""; $continue = true; $injectionClass->getOptions($this->primary_type); @@ -1893,17 +1894,15 @@ private function dataAlreadyInDB($injectionClass, $itemtype) if (!$continue) { $this->values[$itemtype]['id'] = self::ITEM_NOT_FOUND; } else { - $sql = "SELECT * - FROM `" . $injectionClass->getTable() . "`"; - if (!is_a($itemtype, CommonDBTM::class, true)) { throw new HttpException(500, 'Class ' . $itemtype . ' is not a valid class'); } - $item = new $itemtype(); + $item = new $itemtype(); + $where = []; + //If it's a computer device if ($item instanceof CommonDevice) { - $sql .= " WHERE `designation` = '" . - $this->getValueByItemtypeAndName($itemtype, 'designation') . "'"; + $where['designation'] = $this->getValueByItemtypeAndName($itemtype, 'designation'); } elseif ($item instanceof CommonDBRelation) { //Type is a relation : check it this relation still exists //Define the side of the relation to use @@ -1919,49 +1918,41 @@ private function dataAlreadyInDB($injectionClass, $itemtype) $source_itemtype = $item::$itemtype_1; $destination_itemtype = $item::$itemtype_2; } - $where .= " AND `$source_id`='" . - $this->getValueByItemtypeAndName($itemtype, $source_id) . "'"; + $where[$source_id] = $this->getValueByItemtypeAndName($itemtype, $source_id); + $where[$destination_id] = $this->getValueByItemtypeAndName($itemtype, $destination_id); if ($item->isField('itemtype')) { - $where .= " AND `$source_itemtype`='" . - $this->getValueByItemtypeAndName($itemtype, $source_itemtype) . "'"; + $where[$source_itemtype] = $this->getValueByItemtypeAndName($itemtype, $source_itemtype); } - $where .= " AND `" . $destination_id . "`='" . - $this->getValueByItemtypeAndName($itemtype, $destination_id) . "'"; - $sql .= " WHERE 1 " . $where; } else { //Type is not a relation //Type can be deleted if ($injectionClass->maybeDeleted()) { - $where .= " AND `is_deleted` = '0' "; + $where['is_deleted'] = 0; } //Type can be a template if ($injectionClass->maybeTemplate()) { - $where .= " AND `is_template` = '0' "; + $where['is_template'] = 0; } //Type can be assigned to an entity if ($injectionClass->isEntityAssign()) { //Type can be recursive if ($injectionClass->maybeRecursive()) { - $where_entity = getEntitiesRestrictRequest( - " AND", - $injectionClass->getTable(), - "entities_id", - $this->getValueByItemtypeAndName( - $itemtype, + $where = array_merge( + $where, + getEntitiesRestrictCriteria( + $injectionClass->getTable(), 'entities_id', + $this->getValueByItemtypeAndName($itemtype, 'entities_id'), + true, ), - true, ); } else { //Type cannot be recursive - $where_entity = " AND `entities_id` = '" . - $this->getValueByItemtypeAndName($itemtype, 'entities_id') . "'"; + $where['entities_id'] = $this->getValueByItemtypeAndName($itemtype, 'entities_id'); } - } else { //If no entity assignment for this itemtype - $where_entity = ""; } //Add mandatory fields to the query only if it's the primary_type to be injected @@ -1969,44 +1960,48 @@ private function dataAlreadyInDB($injectionClass, $itemtype) foreach ($this->mandatory_fields[$itemtype] as $field => $is_mandatory) { if ($is_mandatory) { if ($item instanceof User && $field == "useremails_id") { - $email = $DB->escape($this->getValueByItemtypeAndName($itemtype, $field)); - $where .= " AND `id` IN (SELECT `users_id` FROM glpi_useremails WHERE `email` = '$email') "; + $where['id'] = new QuerySubQuery([ + 'SELECT' => 'users_id', + 'FROM' => 'glpi_useremails', + 'WHERE' => ['email' => $this->getValueByItemtypeAndName($itemtype, $field)], + ]); } else { - $where .= " AND `" . $field . "`='" . (string) $this->getValueByItemtypeAndName($itemtype, $field) . "'"; + $where[$field] = $this->getValueByItemtypeAndName($itemtype, $field); } } } } else { //Table contains an itemtype field if ($injectionClass->isField('itemtype')) { - $where .= " AND `itemtype` = '" . $this->getValueByItemtypeAndName( - $itemtype, - 'itemtype', - ) . "'"; + $where['itemtype'] = $this->getValueByItemtypeAndName($itemtype, 'itemtype'); } //Table contains an items_id field if ($injectionClass->isField('items_id')) { - $where .= " AND `items_id` = '" . $this->getValueByItemtypeAndName( - $itemtype, - 'items_id', - ) . "'"; + $where['items_id'] = $this->getValueByItemtypeAndName($itemtype, 'items_id'); } } //Add additional parameters specific to this itemtype (or function checkPresent exists) if (method_exists($injectionClass, 'checkPresent')) { - $where .= $injectionClass->checkPresent($this->values, $options); + $extra = $injectionClass->checkPresent($this->values, $options); + if (is_array($extra) && count($extra) > 0) { + $where = array_merge($where, $extra); + } } - $sql .= " WHERE 1 " . $where_entity . " " . $where; } - $result = $DB->doQuery($sql); - if ($DB->numrows($result) > 0) { - $db_fields = $DB->fetchAssoc($result); + + $result = $DB->request([ + 'FROM' => $injectionClass->getTable(), + 'WHERE' => $where, + ]); + + if (count($result) > 0) { + $db_fields = $result->current(); foreach ($db_fields as $key => $value) { $this->setValueForItemtype($itemtype, $key, $value, true); } - $this->setValueForItemtype($itemtype, 'id', $DB->result($result, 0, 'id')); + $this->setValueForItemtype($itemtype, 'id', $db_fields['id']); } else { $this->setValueForItemtype($itemtype, 'id', self::ITEM_NOT_FOUND); } diff --git a/inc/model.class.php b/inc/model.class.php index 26af99be..29b03cf1 100644 --- a/inc/model.class.php +++ b/inc/model.class.php @@ -993,6 +993,7 @@ public function readUploadedFile($options = []) ), ]; } + unset($_FILES['filename']); } //If file has not the right extension, reject it and delete if diff --git a/inc/networkportinjection.class.php b/inc/networkportinjection.class.php index 7d14651d..cdb391a7 100644 --- a/inc/networkportinjection.class.php +++ b/inc/networkportinjection.class.php @@ -184,13 +184,13 @@ public function addOrUpdateObject($values = [], $options = []) * @param array $fields_toinject array * @param array $options array **/ - public function checkPresent($fields_toinject = [], $options = []) + public function checkPresent($fields_toinject = [], $options = []): array { - return $this->getUnicityRequest($fields_toinject['NetworkPort'], $options['checks']); } + /** * @param array $fields_toinject * @param array $options @@ -245,40 +245,38 @@ public function checkParameters($fields_toinject, $options) * @param array $fields_toinject array the fields to insert into DB * @param array $options array * - * @return string the sql where clause + * @return array **/ - public function getUnicityRequest($fields_toinject = [], $options = []) + public function getUnicityRequest($fields_toinject = [], $options = []): array { - - $where = ""; - + $where = []; switch ($options['port_unicity']) { case PluginDatainjectionCommonInjectionLib::UNICITY_NETPORT_LOGICAL_NUMBER: - $where .= " AND `logical_number` = '" . ($fields_toinject["logical_number"] ?? '') . "'"; + $where['logical_number'] = $fields_toinject['logical_number'] ?? ''; break; case PluginDatainjectionCommonInjectionLib::UNICITY_NETPORT_LOGICAL_NUMBER_MAC: - $where .= " AND `logical_number` = '" . ($fields_toinject["logical_number"] ?? '') . "' - AND `mac` = '" . ($fields_toinject["mac"] ?? '') . "'"; + $where['logical_number'] = $fields_toinject['logical_number'] ?? ''; + $where['mac'] = $fields_toinject['mac'] ?? ''; break; case PluginDatainjectionCommonInjectionLib::UNICITY_NETPORT_LOGICAL_NUMBER_NAME: - $where .= " AND `logical_number` = '" . ($fields_toinject["logical_number"] ?? '') . "' - AND `name` = '" . ($fields_toinject["name"] ?? '') . "'"; + $where['logical_number'] = $fields_toinject['logical_number'] ?? ''; + $where['name'] = $fields_toinject['name'] ?? ''; break; case PluginDatainjectionCommonInjectionLib::UNICITY_NETPORT_LOGICAL_NUMBER_NAME_MAC: - $where .= " AND `logical_number` = '" . ($fields_toinject["logical_number"] ?? '') . "' - AND `name` = '" . ($fields_toinject["name"] ?? '') . "' - AND `mac` = '" . ($fields_toinject["mac"] ?? '') . "'"; + $where['logical_number'] = $fields_toinject['logical_number'] ?? ''; + $where['name'] = $fields_toinject['name'] ?? ''; + $where['mac'] = $fields_toinject['mac'] ?? ''; break; case PluginDatainjectionCommonInjectionLib::UNICITY_NETPORT_MACADDRESS: - $where .= " AND `mac` = '" . ($fields_toinject["mac"] ?? '') . "'"; + $where['mac'] = $fields_toinject['mac'] ?? ''; break; case PluginDatainjectionCommonInjectionLib::UNICITY_NETPORT_NAME: - $where .= " AND `name` = '" . ($fields_toinject["name"] ?? '') . "'"; + $where['name'] = $fields_toinject['name'] ?? ''; break; } diff --git a/inc/softwarelicenseinjection.class.php b/inc/softwarelicenseinjection.class.php index 1be2e53c..450b55be 100644 --- a/inc/softwarelicenseinjection.class.php +++ b/inc/softwarelicenseinjection.class.php @@ -200,14 +200,16 @@ public function addSpecificNeededFields($primary_type, $values) /** * @param array $fields_toinject array * @param array $options array + * @retrun array **/ - public function checkPresent($fields_toinject = [], $options = []) + public function checkPresent($fields_toinject = [], $options = []): array { - if ($options['itemtype'] != 'SoftwareLicense') { - return (" AND `softwares_id` = '" . $fields_toinject['Software']['id'] . "' - AND `name` = '" . $fields_toinject['SoftwareLicense']['name'] . "'"); + return [ + 'softwares_id' => $fields_toinject['Software']['id'], + 'name' => $fields_toinject['SoftwareLicense']['name'], + ]; } - return ""; + return []; } } diff --git a/inc/softwareversioninjection.class.php b/inc/softwareversioninjection.class.php index fd627ce4..4e391791 100644 --- a/inc/softwareversioninjection.class.php +++ b/inc/softwareversioninjection.class.php @@ -195,14 +195,16 @@ public function addSpecificNeededFields($primary_type, $values) /** * @param array $fields_toinject array * @param array $options array + * @return array **/ - public function checkPresent($fields_toinject = [], $options = []) + public function checkPresent($fields_toinject = [], $options = []): array { - if ($options['itemtype'] != 'SoftwareVersion') { - return (" AND `softwares_id` = '" . $fields_toinject['Software']['id'] . "' - AND `name` = '" . $fields_toinject['SoftwareVersion']['name'] . "'"); + return [ + 'softwares_id' => $fields_toinject['Software']['id'], + 'name' => $fields_toinject['SoftwareVersion']['name'], + ]; } - return ""; + return []; } }