Skip to main content
Vulnerability Database/CVE-2026-55374

CVE-2026-55374: Canto SaaS API Path Traversal Vulnerability

CVE-2026-55374 is a path traversal vulnerability in the canto-saas-api PHP library that allows attackers to manipulate endpoints through untrusted path variables. This post covers the technical details, affected versions, and mitigation steps.

Published:

CVE-2026-55374 Overview

CVE-2026-55374 is a path traversal vulnerability [CWE-74] in canto-saas-api, a PHP library for interacting with the Canto SaaS API. Versions prior to 3.0.0 fail to encode individual path segments in Request::buildRequestUrl(), which joins values returned by Request::getPathVariables() without sanitization. An attacker who controls a path variable value through the consuming application can inject traversal sequences, query delimiters, or fragment delimiters. These characters change the destination endpoint before AbstractEndpoint::sendRequest() attaches the configured authentication token. The result is unintended reads or writes on the same Canto instance with the application's privileges.

Critical Impact

Attackers who influence untrusted path variables can redirect authenticated API requests to arbitrary endpoints, causing unauthorized reads or writes with the consuming application's Canto privileges.

Affected Products

  • jleehr/canto-saas-api PHP library versions prior to 3.0.0
  • Consuming PHP applications that pass unvalidated path variables to GetContentDetailsRequest
  • Deployments relying on the affected scheme and contentId path variables

Discovery Timeline

  • 2026-09-15 - CVE-2026-55374 published to the National Vulnerability Database (NVD)
  • 2026-09-15 - Last updated in NVD database
  • Fix released - Patched in canto-saas-api version 3.0.0

Technical Details for CVE-2026-55374

Vulnerability Analysis

The flaw sits in the request construction path of the library. Request::buildRequestUrl() concatenates path variables returned by Request::getPathVariables() directly into the outbound URL. The library does not apply per-segment URL encoding to values such as scheme and contentId used by GetContentDetailsRequest.

Because URL encoding is absent, characters with structural meaning in URLs remain intact. Sequences such as ../, ?, and # alter the effective path or introduce query and fragment components. The malformed URL is then passed to AbstractEndpoint::sendRequest(), which attaches the configured OAuth authentication token before dispatching the request.

The result is an authenticated request sent to an attacker-influenced endpoint on the same Canto instance. Applications that only pass trusted, validated identifiers are not exploitable.

Root Cause

The root cause is missing input neutralization when composing a URL from untrusted path segments, an instance of improper neutralization of special elements [CWE-74]. The library treated getPathVariables() output as safe for direct string concatenation rather than encoding each segment with rawurlencode() or an equivalent routine.

Attack Vector

An attacker must control a path variable value that a downstream application forwards to the library without validation. The library then constructs a URL that resolves to a different Canto API endpoint than the developer intended. Because the authentication token is attached after URL construction, the attacker-directed request is fully authenticated with the application's privileges.

php
// Patch excerpt from src/Client.php (v3.0.0)
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 hardening in src/ClientOptions.php warns that enabling httpClientOptions['debug'] causes Guzzle/cURL to write full HTTP traffic, including the Authorization header and OAuth credentials, to STDOUT. Debug mode must not be enabled in production. See the GitHub Security Advisory GHSA-9qfv-wgh2-m6p8 for full advisory details.

Detection Methods for CVE-2026-55374

Indicators of Compromise

  • Outbound HTTP requests from PHP application servers to Canto API endpoints containing %2e%2e, ../, ?, or # characters in path segments
  • Canto API access logs showing requests to endpoints not referenced by the application's normal workflows
  • Unexpected reads or writes on Canto assets that fall outside the application's intended scope

Detection Strategies

  • Inventory PHP projects using jleehr/canto-saas-api via composer.lock and flag any version below 3.0.0
  • Perform static analysis on consumer code to find contentId or scheme values populated from HTTP request data without validation
  • Review Canto instance audit logs for authenticated API calls whose paths diverge from the application's documented endpoints

Monitoring Recommendations

  • Log and alert on outbound Guzzle requests whose URLs contain URL-decoded traversal metacharacters after library invocation
  • Monitor Canto API telemetry for spikes in access to endpoints not associated with the calling application
  • Ensure Guzzle debug mode is disabled in production and monitor for accidental exposure of OAuth credentials in application STDOUT logs

How to Mitigate CVE-2026-55374

Immediate Actions Required

  • Upgrade jleehr/canto-saas-api to version 3.0.0 or later using composer require jleehr/canto-saas-api:^3.0
  • Audit all call sites that pass contentId, scheme, or other path variables into library requests and enforce strict allow-list validation
  • Rotate any OAuth credentials that may have been exposed through debug-mode logging in production environments

Patch Information

The issue is fixed in version 3.0.0 of canto-saas-api. Refer to the GitHub Release Version 3.0.0 and the security patch commit for the complete change set. The fix ensures path segments are properly encoded before URL construction and adds a total request timeout to prevent hanging connections.

Workarounds

  • Validate all path variable inputs against a strict allow-list of expected identifiers before invoking the library
  • Apply rawurlencode() to any user-influenced values passed to GetContentDetailsRequest and related endpoint classes
  • Restrict Canto application credentials to the minimum required scope so that any misdirected authenticated request has limited impact
bash
# Upgrade the vulnerable library to the patched release
composer require jleehr/canto-saas-api:^3.0.0
composer update jleehr/canto-saas-api

# Verify installed version
composer show jleehr/canto-saas-api | grep versions

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.