Safeguard
Application Security•

SAP Cloud SDK for Python CVE-2026-89111: CVSS 10 SSRF Leaks Client Secrets

SAP's October 2026 Patch Day put a pip package at the top of the list. sap-cloud-sdk before 0.45.2 lets a tenant_subdomain value redirect OAuth2 token requests.

Safeguard Security Team
5 min read

SAP's Security Patch Day on 13 October 2026 released 16 new security notes and 4 GitHub security advisories. The highest rated item was not an ABAP system or a portal. It was a Python library: CVE-2026-89111 in the SAP Cloud SDK for Python (sap-cloud-sdk on PyPI), rated Critical with a CVSS score of 10.0.

According to the advisory, an attacker who controls the tenant_subdomain parameter in a multi-tenant SAP BTP application can redirect OAuth2 token requests to a server they control, and the application's client credentials go with the request. CISA's enrichment on the CVE record marks it as automatable with total technical impact, and no known exploitation.

What's affected

  • Package: sap-cloud-sdk (PyPI), the SAP Cloud SDK for Python.
  • Affected: all versions before 0.45.2.
  • Fixed: 0.45.2 and later. GitHub advisory GHSA-4mv3-jxxm-9cx2, SAP note 3797111.
  • Weakness: CWE-918, server-side request forgery. CVSS 3.1 vector AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N.

The timeline is worth noticing. PyPI shows 0.45.2 was uploaded on 21 August 2026, and the advisory was published on 13 October 2026. Teams that update dependencies regularly were already fixed without knowing it. Teams that pinned an older version and wait for an advisory to move were exposed for that whole stretch with nothing in their scanners.

The bug itself is simple. In multi-tenant BTP apps, the SDK builds the tenant's token endpoint by swapping the first DNS label of the configured token URL for the tenant subdomain. The fix, per the advisory, validates tenant_subdomain against RFC 1123 DNS label rules before substitution. In the current source, that check is a single regular expression: letters, digits and hyphens, no leading or trailing hyphen, at most 63 characters. Before the fix, a value containing characters that change the URL's host could point the token request, with client credentials attached, somewhere else.

How to check if you're exposed

Start with the installed version in every environment, not just your lock file:

pip show sap-cloud-sdk | grep -i '^version'

# In a repo
grep -rniE "sap-cloud-sdk" requirements*.txt pyproject.toml poetry.lock uv.lock Pipfile.lock 2>/dev/null

Then find where the tenant subdomain comes from. In multi-tenant apps it is often derived from the incoming request host, a header, a JWT claim or a URL parameter. Any of those is attacker influenced unless your platform validates it first.

grep -rn "tenant_subdomain" --include=*.py src/ app/ 2>/dev/null

If you find code that passes a request derived value straight into an SDK client or call, and you are on a version before 0.45.2, treat the app as exposed. Also check token endpoint logs or egress logs for OAuth2 token requests to hosts outside your BTP identity domain.

What to do now

  1. Upgrade sap-cloud-sdk to 0.45.2 or later. The current release on PyPI is 0.60.1, so most teams can move to the latest and pick up other fixes too. Rebuild and redeploy every service image that bundles it.
  2. Validate tenant identifiers yourself as well. The advisory's workaround is to check tenant_subdomain against an allowlist of known tenant subdomains before passing it to any SDK call. Keep that check after upgrading; an allowlist is stricter than a format check.
  3. Rotate client credentials for the service bindings used by affected apps if you cannot rule out exposure. An SSRF that sends credentials to an attacker cannot be undone by patching.
  4. Restrict egress from BTP apps where you can, so token requests can only reach your identity endpoints.
  5. Check the other developer-facing items from the same Patch Day: cla-assistant 2.13.1 and earlier (CVE-2026-89112, PII disclosure), Yeoman-UI 1.25.1 and earlier (CVE-2026-89116, OS command injection in the VS Code Application Wizard extension), and cloud-security-services-integration-library from 3.6.6 before 4.1.1 (CVE-2026-89105, improper authentication in HybridTokenAuthenticator).

Why it matters

The pattern here is old: a value that looks like an identifier gets concatenated into a URL, and the URL decides where secrets are sent. Multi-tenancy makes it worse, because the tenant name is exactly the thing an attacker gets to choose when they sign up or send a request. Any time code builds a hostname from input, validate it as a DNS label, or better, look it up in a list of known tenants.

The patch gap is the other lesson. Fixed versions often ship weeks before the advisory, and advisory-driven tools see nothing until disclosure. Keeping dependencies current on a routine schedule, and knowing which services actually reach the vulnerable code path, is what closes that gap.

Try it yourself

Export the Python dependencies of one BTP service to a requirements.txt (for example with pip freeze) and drop it into https://gold.safeguard.sh/scan. The scan runs in your browser, the file never leaves your machine, and no login is needed. Then search the service for every place a tenant identifier enters a URL.

Click through it at your own pace, or open it full screen.

Quick check

Which version of sap-cloud-sdk fixes CVE-2026-89111?

Version 0.45.2. All earlier versions are affected. It was published on PyPI on 21 August 2026, weeks before the 13 October advisory.

What does an attacker need to control to exploit it?

The tenant_subdomain parameter in a multi-tenant BTP application. With it, they can redirect OAuth2 token requests to their own server and capture the client credentials.

What is SAP's workaround if you cannot upgrade immediately?

Validate tenant_subdomain against an allowlist of known tenant subdomains before passing it to any SDK call.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.