Summary
An information disclosure vulnerability has been identified in the UPS Shipping Module (upsshipping) for PrestaShop, developed by Agence Web 360.
A remote unauthenticated attacker can retrieve XML log files containing sensitive data (UPS API credentials, shipper account numbers, customer PII, merchant tax identification numbers) by directly requesting predictable URLs in the module’s logs/ directory.
The issue affects:
all known versions of upsshipping, up to and including 2.4.0
The vendor (Agence Web 360, Golfe-Juan, France) is defunct and no official patch is available:
- The domain
agence-web-360.comis listed for sale. - The vendor’s Facebook page has been inactive since 2016.
- Several prior contact attempts received no response.
No patch exists or is expected.
Vulnerability Details
- CVE ID: CVE-2026-39079
- Primary CWE: CWE-552 (Files or Directories Accessible to External Parties)
- Contributing CWE: CWE-532 (Insertion of Sensitive Information into Log File)
- Secondary CWE: CWE-295 (Improper Certificate Validation, in
lib/UPSLocatorApi.php) - CVSS 3.1: 8.6 (High)
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:NScope is rated as Changed because the vulnerability exposes credentials and sensitive technical data belonging to a separate security authority (the merchant’s UPS account / UPS API platform), alongside customer personal data. - Attack Vector: Remote
- Authentication Required: No
- User Interaction: None
- Impact: Information Disclosure (credentials, PII)
Affected Components
/modules/upsshipping/logs/
/modules/upsshipping/lib/UPSBaseApi.php
/modules/upsshipping/lib/UPSLocatorApi.php
Technical Description
Root Cause
The exploitability of this vulnerability comes from the absence of access control on the logs/ directory. Any file written there is directly reachable over HTTP, without authentication and without user interaction.
Four layers of protection that would have prevented the exploit are all missing on the logs/ directory:
- No
.htaccessfile blocks web access to the logs directory. None is shipped anywhere in the module (neither inlogs/nor at the module root). - No
index.phpguard insidelogs/. The rest of the module follows the PrestaShop convention of shipping a blankindex.phpin every subdirectory (upgrade/,mails/,exports/,classes/,controllers/,views/,tests/, etc.) to block directory listing. Thelogs/directory is the only subdirectory of the module without one. - No web-server-side restriction on the path. The module’s installation procedure does not instruct the merchant to harden the directory at the server level.
- No filename unpredictability. Filenames follow a deterministic pattern based on
time()(UPSRatingApi-request-{unix_timestamp}.xml,UPSShippingApi-request-{unix_timestamp}.xml,UPSTrackingApi-request-{unix_timestamp}.xml, and their-response-counterparts). Using random tokens instead of a timestamp would have prevented blind enumeration even in the absence of access control.
The combination of a publicly writable directory, no access control, and predictable filenames makes exploitation trivial.
Note that files in this directory are named using time():
// lib/UPSBaseApi.php
$fw = fopen(dirname(__FILE__)."/../logs/".get_class($this)."-request-".time().".xml", 'w+');
fwrite($fw, $client->__getLastRequest());
fclose($fw);
$fw = fopen(dirname(__FILE__)."/../logs/".get_class($this)."-response-".time().".xml", 'w+');
fwrite($fw, $client->__getLastResponse());
fclose($fw);
Because filenames are based on Unix timestamps, and because the logs/ directory ships without an index.php guard and without an .htaccess blocking web access, enumeration and direct retrieval of historical files is trivial for an attacker.
Unconditional Logging in the Exception Handler
In lib/UPSBaseApi.php, two distinct logging blocks exist:
- Inside the
catch (Exception $e)block, with no condition. It is executed on every SOAP error. - After the
try/catchblock, gated byif ($this->log)and intended for debug mode only.
try {
$this->response = $client->__soapCall($this->operation, array($this->request));
} catch (Exception $e) {
// Unconditional logging, bypasses the debug flag
$fw = fopen(dirname(__FILE__)."/../logs/".get_class($this)."-request-".time().".xml", 'w+');
fwrite($fw, $client->__getLastRequest());
fclose($fw);
$fw = fopen(dirname(__FILE__)."/../logs/".get_class($this)."-response-".time().".xml", 'w+');
fwrite($fw, $client->__getLastResponse());
fclose($fw);
// ...
throw $exc;
}
if ($this->log) {
/* debug-only block (also writes credentials + PII to disk) */
}
Even when the merchant has not enabled debug mode, every UPS API error (invalid tracking number, timeout, validation rejection, etc.) writes the full SOAP request, including credentials and PII, to a publicly accessible file.
Ineffective Log Rotation
The module implements a clearLogs() routine intended to delete files older than 30 minutes, but it is only triggered from inside the module code path and does not run reliably. On a confirmed affected instance, logs were retained for more than three years.
Secondary Weakness: Disabled TLS Verification
In lib/UPSLocatorApi.php, TLS certificate validation is disabled when contacting the UPS endpoint:
curl_setopt($rsrcCurl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($rsrcCurl, CURLOPT_SSL_VERIFYHOST, 0);
This enables man-in-the-middle interception of Locator API traffic (CWE-295).
Proof of Concept
An unauthenticated remote attacker can directly access XML log files via predictable URLs:
https://target.example/modules/upsshipping/logs/UPSRatingApi-request-{unix_timestamp}.xml
https://target.example/modules/upsshipping/logs/UPSShippingApi-request-{unix_timestamp}.xml
https://target.example/modules/upsshipping/logs/UPSTrackingApi-request-{unix_timestamp}.xml
Example of exposed data in a single request file (values redacted):
<ns3:Username>XXXXXX (real username)</ns3:Username>
<ns3:Password>XXXXXX (real password)</ns3:Password>
<ns3:AccessLicenseNumber>XXC2BB3311XXXXXX</ns3:AccessLicenseNumber>
<ns2:ShipperNumber>3XYXXX</ns2:ShipperNumber>
<ns2:TaxIdentificationNumber>FR00819XXXX</ns2:TaxIdentificationNumber>
<ns2:Name>Customer Name</ns2:Name>
<ns2:Phone><ns2:Number>460768XXXXXX</ns2:Number></ns2:Phone>
<ns2:AddressLine>Västervägen XX</ns2:AddressLine>
<ns2:City>Vindeln</ns2:City>
<ns2:PostalCode>922 31</ns2:PostalCode>
<ns2:CountryCode>SE</ns2:CountryCode>
Three API types are logged:
UPSRatingApi-*: rate quote requests (credentials + sender/recipient address)UPSTrackingApi-*: tracking lookup requests (credentials + tracking numbers)UPSShippingApi-*: shipment creation (credentials + full sender/recipient PII + tax identification number)
Impact
A remote unauthenticated attacker can directly retrieve:
- Valid UPS API credentials (
Username,Password,AccessLicenseNumber) of the affected merchant. - The UPS shipper account number (
ShipperNumber). - The merchant’s VAT / tax identification number.
- Customer personally identifiable information: full names, postal addresses, phone numbers, order references.
Downstream consequences
The vulnerability itself is an information disclosure and does not give the attacker write access. The nature of the exposed data still leads to significant secondary impacts:
- The harvested UPS credentials can be re-used by the attacker to create fraudulent shipments billed to the merchant’s UPS account, affecting a separate security authority (UPS).
- Exposure of customer PII over an extended period is likely to trigger GDPR breach-notification obligations for the affected merchant.
Real-World Exploitation Scope
On a single confirmed affected instance:
- 2,381,841 XML log files (~ 8.7 GB).
- Time range: February 2023 to April 2026 (more than three years of continuously exposed data).
- File distribution:
UPSTrackingApi-request: 1,056,893UPSTrackingApi-response: 1,056,885UPSRatingApi-response: 134,530UPSRatingApi-request: 134,522UPSShippingApi-request: 11UPSShippingApi-response: 11
Despite the clearLogs() routine, log retention was effectively indefinite.
Patch
No vendor patch exists or is expected. The vendor is defunct and unreachable.
Primary recommendation: remove the module
The vendor is defunct and no patch will ever be released. The only durable remediation is to completely remove the upsshipping module from the PrestaShop installation and migrate to a maintained shipping module.
Disabling the module from the PrestaShop back office is not sufficient: the files remain on disk and the logs/ directory remains reachable over HTTP. The module must be fully uninstalled and the modules/upsshipping/ directory deleted from the filesystem.
After removal, also:
- Purge any remaining XML files from
modules/upsshipping/logs/if the directory was left behind. - Rotate UPS API credentials (change the UPS account password and request a new
AccessLicenseNumberfrom UPS). Assume any historical credentials are compromised. - Review UPS account activity for unauthorized shipments billed to the shipper account.
- Review access logs to the
logs/directory and assess GDPR notification obligations. Customer PII (names, addresses, phone numbers) has been publicly exposed for an extended period; merchants should evaluate breach-notification duties to their supervisory authority and to the affected data subjects.
Temporary hardening (only if the module cannot be removed immediately)
Merchants who still depend on this module while a migration is in progress should, at a minimum:
Block public access to the
logs/directory at the web-server level. This is the most important mitigation, since it neutralises the exploit even if the existing logs remain on disk.Apache, drop-in
.htaccess(recommended). Create a file atmodules/upsshipping/logs/.htaccesswith the following content:# Block all HTTP access to this directory and its contents. # Apache 2.4+ <IfModule mod_authz_core.c> Require all denied </IfModule> # Apache 2.2 fallback <IfModule !mod_authz_core.c> Order deny,allow Deny from all </IfModule> # Defense in depth: disable directory listing and script execution Options -Indexes -ExecCGI <FilesMatch ".*"> SetHandler default-handler </FilesMatch>Apache, alternative scoped from the PrestaShop root
.htaccess(useful ifAllowOverrideis restricted):<LocationMatch "^/modules/upsshipping/logs/"> Require all denied </LocationMatch>nginx equivalent (inside the
serverblock):location ^~ /modules/upsshipping/logs/ { deny all; return 403; }After deployment, verify the fix by requesting any known log URL. The server must return
403 Forbidden(or404for the nginx variant).Purge all existing XML log files in
modules/upsshipping/logs/.Rotate UPS API credentials: change the UPS account password and request a new
AccessLicenseNumberfrom UPS. Assume any historical credentials are compromised.Review UPS account activity for any unauthorized shipments billed to the shipper account.
These steps reduce exposure but do not fix the underlying issue. They should be treated as a holding measure while the module is being replaced, not as a long-term solution.
Additional Security Recommendations
These recommendations apply to any PrestaShop installation, not only to this specific module.
Inventory all installed modules and identify those whose vendor is no longer active. A module from a defunct vendor will never receive a security fix and should be removed, not merely disabled. Disabling a module from the back office leaves the files on disk and any directly reachable resources (logs, exports, debug pages) remain exposed.
Restrict direct HTTP access to module subdirectories that should never be web-reachable (
logs/,cache/,tmp/,tests/,exports/, etc.) at the web-server level, as a defense-in-depth measure independent of module-shipped.htaccessorindex.phpguards.Review the use of verbose logging in production. Any logging mechanism that writes credentials, tokens or PII to disk should be disabled, regardless of vendor “debug flags”. When logs are unavoidable, store them outside the web root and use unpredictable filenames.
Monitor third-party module vulnerabilities. Use a solution that tracks known vulnerabilities affecting PrestaShop modules (for example PrestaScan Security or Zentria).
Deploy perimeter protection. Configure a Web Application Firewall (WAF) to block suspicious requests targeting common module log/debug paths and to rate-limit enumeration attempts.
Timeline
- 2026-03-23: Vulnerability discovered during a security audit
- 2026-04-01: CVE request submitted to MITRE
- 2026-05-16: MITRE assigned CVE-2026-39079
- 2026-05-18: Publication of the CVE
Vendor notification was not possible: the vendor is defunct, the domain is for sale, and previous contact attempts over the past years for a similar issue received no response.
References
- http://agence-web-360.com/ (vendor domain, listed for sale)
- https://www.facebook.com/people/Agence-Web-360/100063715947036/ (vendor Facebook page, inactive since 2016)
- https://www.plugineo.com/fr/prestashop/2-module-ups-pour-prestashop.html (former module distribution page, no longer available)
Credits
Discoverer:
Esokia (Researcher: Maxime Morel-Bailly)Technical assistance:
Profileo.com / 772424.com
Disclaimer
This advisory is published for defensive and informational purposes.
As no vendor patch is available and the vendor is defunct, merchants using the upsshipping module are strongly encouraged to fully remove the module from their installation (uninstall plus deletion of modules/upsshipping/ on the filesystem), rotate their UPS credentials, and migrate to a maintained shipping module. The temporary mitigations described above only reduce exposure and should not be treated as a substitute for removal.