Skip to content

Commit 1a6aadb

Browse files
committed
Fix: validate item type and rights in lifecycle actions
1 parent 3d93cc1 commit 1a6aadb

6 files changed

Lines changed: 44 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

8+
## [Unreleased]
9+
10+
### Fixed
11+
12+
- Fix uninstall/replace actions processing items without checking item type or user rights on the item
13+
814
## [2.10.4] - 2026-08-04
915

1016
### Fixed

ajax/locations.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
&& $_POST['templates_id']
3939
) {
4040
$location = PluginUninstallPreference::getLocationByUserByEntity(
41-
$_POST["users_id"],
41+
Session::getLoginUserID(),
4242
$_POST["templates_id"],
4343
$_POST["entity"],
4444
);

front/action.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@
4040
Html::back();
4141
}
4242

43+
/** @var array $UNINSTALL_TYPES */
44+
global $UNINSTALL_TYPES;
45+
if (!in_array($_REQUEST["device_type"], $UNINSTALL_TYPES, true)) {
46+
Html::back();
47+
}
48+
4349
if (isset($_REQUEST["locations_id"])) {
4450
$location = $_REQUEST["locations_id"];
4551
} else {
@@ -51,6 +57,7 @@
5157
}
5258

5359
if (isset($_REQUEST["replace"])) {
60+
Session::checkRight(PluginUninstallUninstall::$rightname, PluginUninstallProfile::RIGHT_REPLACE);
5461
PluginUninstallReplace::replace(
5562
$_REQUEST["device_type"],
5663
$_REQUEST["model_id"],

inc/model.class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ public function showForm($ID, $options = [])
279279
echo "</td>";
280280
echo "<td rowspan='4'>" . __s('Comments') . "</td>";
281281
echo "<td rowspan='4'>";
282-
echo "<textarea cols='60' rows='4' name='comment'>" . $this->fields["comment"] . "</textarea>";
282+
echo "<textarea cols='60' rows='4' name='comment'>" . htmlentities((string) $this->fields["comment"]) . "</textarea>";
283283
echo "</td></tr>";
284284

285285
echo "<tr class='tab_bg_1'><td>" . __s('New status of the computer', 'uninstall') . "</td>";

inc/replace.class.php

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,28 @@ public static function replace($type, $model_id, $tab_ids, $location)
114114
}
115115

116116
$olditem = new $type();
117-
$olditem->getFromDB($olditem_id);
117+
if (!$olditem->getFromDB($olditem_id) || !$olditem->can($olditem_id, UPDATE)) {
118+
continue;
119+
}
118120

119121
$newitem = new $type();
120-
$newitem->getFromDB($newitem_id);
122+
if (!$newitem->getFromDB($newitem_id) || !$newitem->can($newitem_id, UPDATE)) {
123+
continue;
124+
}
125+
126+
if (
127+
$model->fields['replace_method'] == self::METHOD_PURGE
128+
&& !$olditem->can($olditem_id, PURGE)
129+
) {
130+
continue;
131+
}
132+
133+
if (
134+
$model->fields['replace_method'] == self::METHOD_DELETE_AND_COMMENT
135+
&& !$olditem->can($olditem_id, DELETE)
136+
) {
137+
continue;
138+
}
121139

122140
//Hook to perform actions before item is being replaced
123141
$olditem->fields['_newid'] = $newitem_id;
@@ -839,11 +857,11 @@ public static function showReplacementForm($type, $model_id, $tab_ids, $location
839857
echo "<td>" . $commonitem->getName() . "</td>";
840858

841859
if (Search::getOptionNumber($type, 'otherserial')) {
842-
echo "<td>" . $commonitem->fields['otherserial'] . "</td>";
860+
echo "<td>" . htmlentities((string) $commonitem->fields['otherserial']) . "</td>";
843861
}
844862

845863
if (Search::getOptionNumber($type, 'serial')) {
846-
echo "<td>" . $commonitem->fields['serial'] . "</td>";
864+
echo "<td>" . htmlentities((string) $commonitem->fields['serial']) . "</td>";
847865
}
848866

849867
echo "<td>";

inc/uninstall.class.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,12 @@ public static function processMassiveActionsForOneItemtype(MassiveAction $ma, Co
117117
if ($ma->getAction() === "uninstall") {
118118
$itemtype = $ma->getItemtype(false);
119119
foreach ($ids as $id) {
120-
if ($item->getFromDB($id)) {
120+
if ($item->getFromDB($id) && $item->can($id, UPDATE)) {
121121
//Session::addMessageAfterRedirect(sprintf(__s('Form duplicated: %s', 'formcreator'), $item->getName()));
122122
$_SESSION['glpi_uninstalllist'][$itemtype][$id] = $id;
123123
$ma->itemDone($item->getType(), $id, MassiveAction::ACTION_OK);
124+
} else {
125+
$ma->itemDone($item->getType(), $id, MassiveAction::ACTION_NORIGHT);
124126
}
125127
}
126128

@@ -373,7 +375,9 @@ public static function uninstall($type, $model_id, $tab_ids, $location)
373375
$count++;
374376
if (class_exists($type) && is_a($type, CommonDBTM::class, true)) {
375377
$item = new $type();
376-
$item->getFromDB($id);
378+
if (!$item->getFromDB($id) || !$item->can($id, UPDATE)) {
379+
continue;
380+
}
377381

378382
self::doOneUninstall($model, $transfer, $item, [
379383
'type' => $type,
@@ -476,6 +480,7 @@ public static function deleteComputerInOCS($ocs_id, $ocs_server_id)
476480
global $DB;
477481
if (class_exists('PluginOcsinventoryngOcsServer')) {
478482
$DBocs = PluginOcsinventoryngOcsServer::getDBocs($ocs_server_id)->getDB();
483+
$ocs_id = (int) $ocs_id;
479484

480485
//First try to remove all the network ports
481486
$query = "DELETE

0 commit comments

Comments
 (0)