CVE-2026-55375 Overview
CVE-2026-55375 affects canto-saas-api, a PHP library for interacting with the Canto Software-as-a-Service (SaaS) API. The OAuth2Request::getQueryParams() method places app_id, app_secret, refresh_token, and code in the URL query string of token POST requests. Access logs, proxy logs, and application performance monitoring (APM) traces persist those credentials in plaintext. When a token request fails, OAuth2::obtainAccessToken() passes the credential-bearing Guzzle request URI into AuthorizationFailedException, so application logs and error trackers record the same secrets. This is an information disclosure through error message weakness [CWE-209].
Critical Impact
An attacker with access to affected telemetry can obtain Canto credentials and request access tokens for the tenant.
Affected Products
- jleehr/canto-saas-api PHP library prior to version 3.0.0
- Applications that integrate the library and forward Guzzle traces to logs or APM tools
- Downstream systems that ingest reverse-proxy or web-server access logs containing the request URIs
Discovery Timeline
- 2026-09-15 - CVE-2026-55375 published to the National Vulnerability Database (NVD)
- 2026-09-15 - Last updated in NVD database
Technical Details for CVE-2026-55375
Vulnerability Analysis
The library issues OAuth2 token requests using HTTP POST, but embeds sensitive parameters in the request URI rather than the request body. The OAuth2Request::getQueryParams() method returns app_id, app_secret, refresh_token, and code as query string parameters. Any component that observes the URI, including web server access logs, reverse proxies, load balancers, and APM agents, captures the credentials verbatim.
The second flaw amplifies exposure during failure paths. When OAuth2::obtainAccessToken() cannot obtain a token, it passes the full Guzzle request URI into AuthorizationFailedException. Downstream error trackers, exception aggregators, and log pipelines then persist the credentials in searchable storage.
An attacker who reads any of this telemetry can replay the app_id, app_secret, or refresh_token values to mint valid access tokens for the affected Canto tenant.
Root Cause
The root cause is insertion of sensitive authentication material into a URI that is treated as non-sensitive by every layer of the HTTP stack. The exception handling path then propagates the same URI into thrown exceptions instead of stripping credentials before serialization.
Attack Vector
Exploitation does not require direct interaction with the vulnerable application. An attacker needs read access to logs, APM traces, error tracker events, or any monitoring surface that captured a prior token request. Once credentials are recovered, the attacker performs standard OAuth2 token issuance against the Canto tenant.
// Security patch in src/Client.php - hardens HTTP client configuration
protected function buildHttpClient(): ClientInterface
{
$httpClientOptions = $this->options->getHttpClientOptions();
return new \GuzzleHttp\Client([
'allow_redirects' => true,
'connect_timeout' => (int)$httpClientOptions['timeout'],
// Also enforce a total request timeout; otherwise a server that
// accepts the connection but never responds blocks the caller
// indefinitely.
'timeout' => (int)$httpClientOptions['timeout'],
'debug' => (bool)$httpClientOptions['debug'],
'headers' => [
'userAgent' => $httpClientOptions['userAgent'],
],
]);
}
// Source: https://github.com/jleehr/canto-saas-api/commit/300559fdae5d1bed2dc00a6477f5996833a77339
The accompanying ClientOptions change documents that enabling httpClientOptions['debug'] causes Guzzle and cURL to write the complete HTTP traffic, including the Authorization header and OAuth credentials, to STDOUT. See the GitHub Security Advisory GHSA-37pm-83g7-r22v for the full patch context.
Detection Methods for CVE-2026-55375
Indicators of Compromise
- Web server or reverse proxy access log entries containing app_id=, app_secret=, refresh_token=, or code= query parameters on OAuth token endpoints
- APM traces or transaction spans that expose the same parameters in the recorded HTTP request URI
- AuthorizationFailedException stack traces in error tracking systems that include a Canto OAuth token URL with query string credentials
Detection Strategies
- Search historical log storage, SIEM indexes, and APM back ends for the parameter names above scoped to Canto OAuth endpoints
- Audit exception aggregators (for example Sentry, Rollbar, Bugsnag) for events referencing OAuth2::obtainAccessToken or AuthorizationFailedException
- Inventory all systems and third parties that receive log or trace exports and confirm which retained the credential-bearing URIs
Monitoring Recommendations
- Add log-pipeline scrubbing rules that redact app_secret, refresh_token, and code query parameters at ingestion
- Alert on unexpected Canto API token issuance patterns, especially issuance from new source IP addresses or at unusual times
- Track deployed versions of jleehr/canto-saas-api across build artifacts and container images to identify hosts still running vulnerable releases
How to Mitigate CVE-2026-55375
Immediate Actions Required
- Upgrade jleehr/canto-saas-api to version 3.0.0 or later across all applications
- Rotate every app_secret, refresh_token, and authorization code that may have transited a vulnerable release
- Purge or redact retained logs, APM traces, and exception events that contain the leaked credentials
- Disable httpClientOptions['debug'] in production, since it writes full HTTP traffic including credentials to STDOUT
Patch Information
The fix is available in canto-saas-api release 3.0.0. The remediation commit 300559f hardens the HTTP client configuration and accompanies the query-string removal documented in the advisory.
Workarounds
- Configure reverse proxies and web servers to strip query strings from access log entries for Canto OAuth token endpoints
- Inject a preconfigured Guzzle httpClient via ClientOptions that logs neither request URIs nor headers
- Restrict access to APM and error tracker projects that historically ingested traffic from the affected application
# Update the library via Composer to the fixed release
composer require jleehr/canto-saas-api:^3.0.0
composer update jleehr/canto-saas-api
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

