CVE-2026-8802 Overview
CVE-2026-8802 is a path traversal vulnerability [CWE-22] in Open Source Point of Sale (opensourcepos) versions up to 3.4.2. The flaw exists in the getPicThumb function within app/Controllers/Items.php. Attackers can manipulate the pic_filename argument to traverse outside the intended uploads/item_pics/ directory. The vulnerability is remotely exploitable and requires low-privileged authenticated access.
The maintainers addressed the issue in commit def0c27a0e252668df8d942fc31e16d1edfd7323, which sanitizes the filename using PHP's basename() function and validates file extensions against an allowlist.
Critical Impact
Authenticated remote attackers can read arbitrary files on the server filesystem by injecting ../ sequences into the pic_filename parameter, exposing application source code, configuration files, and other sensitive data.
Affected Products
- opensourcepos Open Source Point of Sale versions up to and including 3.4.2
- The app/Controllers/Items.php controller component
- Deployments exposing the getPicThumb endpoint to authenticated users
Discovery Timeline
- 2026-05-18 - CVE CVE-2026-8802 published to NVD
- 2026-05-18 - Last updated in NVD database
Technical Details for CVE-2026-8802
Vulnerability Analysis
The getPicThumb function in app/Controllers/Items.php accepts a pic_filename parameter and uses it to locate thumbnail images on disk. Before the patch, the controller called rawurldecode() on the user-supplied filename and passed the result directly to glob() and pathinfo() without stripping directory components.
An attacker can supply values such as ..%2F..%2Fapp%2FConfig%2FDatabase.php to escape the ./uploads/item_pics/ base directory. The rawurldecode() call transforms the encoded sequences into literal ../ segments, allowing traversal to arbitrary filesystem locations the web server process can read.
Root Cause
The root cause is missing input sanitization on a filename parameter used in filesystem operations. The original implementation trusted the decoded value of pic_filename and did not enforce that the resolved path remained within the intended upload directory. There was also no allowlist validation of file extensions.
Attack Vector
Exploitation requires network access to the application and a low-privileged authenticated session. An attacker submits a crafted HTTP request to the route handled by getPicThumb, supplying URL-encoded traversal sequences in the pic_filename argument. The server then attempts to load files outside the upload directory.
{
helper('file');
- $pic_filename = rawurldecode($pic_filename);
- $file_extension = pathinfo($pic_filename, PATHINFO_EXTENSION);
+ // Security: Sanitize filename to prevent path traversal
+ // Use basename() to strip directory components and prevent '../' attacks
+ $pic_filename = basename(rawurldecode($pic_filename));
+ $file_extension = strtolower(pathinfo($pic_filename, PATHINFO_EXTENSION));
+
+ // Validate file extension against system-configured allowed image types
+ // Handle both legacy pipe-separated and current comma-separated formats
+ // Fallback to types that GD library can process for thumbnail generation
+ $allowed_types = $this->config['image_allowed_types'] ?? 'jpg,jpeg,gif,png,webp,bmp,tif,tiff';
+ $allowed_extensions = strpos($allowed_types, '|') !== false
+ ? explode('|', $allowed_types)
+ : explode(',', $allowed_types);
+
+ if (!in_array($file_extension, $allowed_extensions, true)) {
+ return $this->response->setStatusCode(400)->setBody('Invalid file type');
+ }
+
$images = glob("./uploads/item_pics/$pic_filename");
$base_path = './uploads/item_pics/' . pathinfo($pic_filename, PATHINFO_FILENAME);
Source: GitHub Commit def0c27. The patch wraps the decoded filename with basename() to strip any directory components and rejects requests whose extension is not in the configured allowlist.
Detection Methods for CVE-2026-8802
Indicators of Compromise
- HTTP requests to Items controller routes containing ../, ..%2F, or ..%5C sequences within the pic_filename parameter.
- Web server access logs showing successful 200 responses for pic_filename values referencing files outside uploads/item_pics/, such as Database.php or .env.
- PHP glob() errors or unusual file read activity originating from the Items controller process.
Detection Strategies
- Inspect web application firewall (WAF) and reverse proxy logs for encoded traversal patterns targeting the getPicThumb endpoint.
- Deploy file integrity monitoring on application configuration files and credential stores referenced by the Open Source Point of Sale deployment.
- Correlate authenticated session activity with anomalous pic_filename query strings to surface low-and-slow enumeration attempts.
Monitoring Recommendations
- Alert on repeated 4xx and 5xx responses from the Items controller, which can indicate fuzzing of the filename parameter.
- Monitor outbound responses for content types that do not match expected image MIME types when served from the thumbnail endpoint.
- Capture and retain full URI query strings in access logs to support post-incident traversal analysis.
How to Mitigate CVE-2026-8802
Immediate Actions Required
- Apply commit def0c27a0e252668df8d942fc31e16d1edfd7323 or upgrade to a release that includes pull request #4545.
- Restrict access to the Open Source Point of Sale administrative interface to trusted networks while patching is in progress.
- Audit web server logs for prior exploitation attempts referencing pic_filename with traversal sequences.
Patch Information
The upstream fix is published in the GitHub Security Advisory GHSA-xq63-3v4g-39r5 and merged via pull request #4545. The patch enforces basename() sanitization on the decoded filename and validates the extension against the configured image_allowed_types list. Administrators should pull the latest release branch and redeploy the application.
Workarounds
- Place a WAF rule in front of the application that blocks requests containing .., %2e%2e, or %2f sequences in the pic_filename parameter.
- Configure the web server to deny direct access to sensitive files such as .env, Config/*.php, and database credentials at the filesystem layer.
- Run the PHP process under a least-privilege user account that lacks read access to files outside the application's public and writable directories.
# Example ModSecurity rule to block traversal attempts on the thumbnail endpoint
SecRule REQUEST_URI "@contains getPicThumb" \
"chain,deny,status:400,id:1026880201,msg:'CVE-2026-8802 path traversal attempt'"
SecRule ARGS:pic_filename "@rx (\.\.|%2e%2e|%2f|%5c)" "t:lowercase,t:urlDecodeUni"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


