CVE-2026-110226 Overview
CVE-2026-110226 is a broken access control vulnerability in QloApps through version 1.7.0, an open-source hotel reservation and booking system. The flaw allows back-office employees whose profiles are restricted to specific hotels to create room types under hotels they are not authorized to manage. Attackers enumerate every hotel through an unfiltered form selector, then submit a forged id_hotel parameter to AdminProductsController. The controller trusts the supplied hotel identifier without re-validating profile-level authorization, enabling unauthorized room and inventory creation across tenant boundaries. The weakness is categorized under CWE-639 (Authorization Bypass Through User-Controlled Key).
Critical Impact
Hotel-restricted employees can create rooms and inventory under any hotel in the deployment, breaking multi-tenant isolation and polluting foreign property catalogs.
Affected Products
- QloApps through version 1.7.0
- controllers/admin/AdminProductsController.php (room type creation endpoints)
- modules/hotelreservationsystem/classes/HotelBranchInformation.php (hotel enumeration helper)
Discovery Timeline
- 2026-10-13 - CVE-2026-110226 published to NVD
- 2026-10-13 - Last updated in NVD database
Technical Details for CVE-2026-110226
Vulnerability Analysis
QloApps implements a profile-based access control model where back-office employees are associated with a subset of hotels via their id_profile. The room type creation workflow in AdminProductsController is supposed to honor this scoping. Instead, the controller populates the hotel selector by calling HotelBranchInformation::hotelsNameAndId(), which returns every hotel in the database regardless of profile assignment. A restricted employee can therefore see other properties in the dropdown and, more importantly, submit any id_hotel value in the POST request. The server-side handler persists the room and inventory records against that foreign hotel ID without rechecking that the acting employee is authorized for it.
Root Cause
The root cause is a missing authorization check on the user-controlled id_hotel parameter. The code path uses the unfiltered enumeration helper hotelsNameAndId() instead of a profile-aware equivalent. There is no server-side verification that the submitted hotel identifier intersects with the employee's permitted hotels before AdminProductsController writes room data.
Attack Vector
An authenticated back-office user with limited hotel scope opens the room type creation form, inspects the rendered hotel selector or its backing AJAX response, and extracts the full list of id_hotel values. The attacker then submits the room creation request with an id_hotel belonging to a hotel outside their assigned scope. The controller accepts the value and provisions the room and inventory under the targeted property.
// Patched code from AdminProductsController.php
// Source: https://github.com/Qloapps/QloApps/commit/24ff5f5e6ba0c7a42c83ce8155b318c3ef8c915d
if ($obj->id) {
if ($this->product_exists_in_shop) {
$objHotelInfo = new HotelBranchInformation();
- $hotelInfo = $objHotelInfo->hotelsNameAndId();
+ $hotelInfo = HotelBranchInformation::getProfileAccessedHotels($this->context->employee->id_profile, 1);
if ($hotelInfo) {
$objRoomInfo = new HotelRoomInformation();
$roomStatus = $objRoomInfo->getAllRoomStatus();
The patch replaces the unrestricted enumeration call with getProfileAccessedHotels(), which returns only hotels authorized for the current employee profile. A companion template change in informations.tpl guards against rendering the selector when no hotels are available.
Detect Identity Attacks the Moment Authentication Fails
Singularity™ Identity surfaces credential misuse, lateral movement, and privilege escalation in real time, so you can contain the breach before it spreads.
Stop Identity AttacksDetection Methods for CVE-2026-110226
Indicators of Compromise
- Room type or inventory records in ps_htl_room_information and related tables whose id_hotel does not match any hotel assigned to the creating employee's profile.
- Admin audit log entries showing room creations by employees who historically only operated on a single hotel suddenly touching multiple id_hotel values.
- Unexpected growth in product and room catalogs under hotels administered by other staff.
Detection Strategies
- Correlate id_employee, id_profile, and the targeted id_hotel in the admin controller access logs to flag cross-hotel writes.
- Replay recent AdminProductsController POST requests and compare the submitted id_hotel against HotelBranchInformation::getProfileAccessedHotels() output for the acting profile.
- Alert on web requests to index.php?controller=AdminProducts where the id_hotel POST parameter is set by a non-superadmin account.
Monitoring Recommendations
- Enable verbose logging on admin controllers and ingest the logs into a SIEM for cross-tenant anomaly analysis.
- Baseline the normal id_hotel usage per employee and alert on first-seen deviations.
- Review commit 24ff5f5e and the VulnCheck advisory to tune detections.
How to Mitigate CVE-2026-110226
Immediate Actions Required
- Apply the fix from Pull Request #1649 or upgrade to a QloApps build that includes commit 24ff5f5e.
- Audit all room and inventory records created on or before the patch date and remove entries written by employees to hotels outside their profile scope.
- Reduce the privileges of back-office profiles that do not require room type creation until the patch is deployed.
Patch Information
The upstream fix is delivered in QloApps commit 24ff5f5e, merged through Pull Request #1649. The patch swaps the unrestricted HotelBranchInformation::hotelsNameAndId() call for HotelBranchInformation::getProfileAccessedHotels($this->context->employee->id_profile, 1) in AdminProductsController.php and updates informations.tpl to only render the hotel selector when accessible hotels exist.
Workarounds
- Restrict the Products admin tab to superadmin profiles until the patch is applied, preventing scoped employees from reaching the vulnerable form.
- Place a web application firewall rule in front of index.php?controller=AdminProducts that rejects POST requests where id_hotel is not in the acting employee's allowed list.
- Monitor and manually review new room type creations until upgrade is complete.
# Apply the upstream patch to a QloApps 1.7.0 deployment
cd /var/www/qloapps
git fetch origin
git cherry-pick 24ff5f5e6ba0c7a42c83ce8155b318c3ef8c915d
# Clear the admin cache after deployment
rm -rf var/cache/*
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

