Skip to main content
SAP Pentest Playbook
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage
Edit page

SAP Cloud Connector Principal Propagation Impersonation

Description

Principal Propagation (PP) is a legitimate SCC feature: for a Cloud-To-On-Premise mapping configured with a PP-capable authentication mode, SCC forwards the identity of an authenticated cloud caller to the on-prem backend by minting a short-lived X.509 client certificate - in LOCAL mode, signed by SCC’s own local CA - whose subject DN is built from a configurable <subjectPattern> template containing placeholders bound to the cloud caller’s IdP claims (${name}, ${email}, ${first_name}, ${last_name}, or the stable ${user_uuid}). The on-prem ABAP kernel then resolves the certificate’s CN against USREXTID (TYPE=DN/TYPE=LD rows, or USR02 directly if login/certificate_mapping_rulebased=1) to decide which ABAP user the request runs as.

If the subject-pattern binds CN to a claim the cloud caller can freely choose, and no <condition> narrows which cloud identities the rule applies to, any cloud caller who can present an arbitrary IdP claim becomes any on-prem ABAP user whose CN matches - including DDIC, SAP*, or other privileged service accounts, if a USREXTID mapping happens to exist for them. This is verifiable two ways: a static config audit over the extracted <principalPropagationConfiguration> and USREXTID, and a live end-to-end probe through the real BTP connectivity proxy and SCC tunnel that reads back the actual impersonated ABAP username.

Risk

  • Critical: CN is a hardcoded privileged literal (e.g. CN=DDIC) - every cloud caller through that mapping becomes that privileged user; or CN is caller-controlled, mode is LOCAL, and no <condition> is set - any cloud caller picks any on-prem CN.
  • High: CN is caller-controlled but a <condition> narrows eligible callers (still risky - CN itself remains attacker-chosen within the allowed set); or CN is caller-controlled under a non-LOCAL PP mode (Kerberos/SAP Secure Login Server), where blast radius depends on the external issuer’s trust scope.
  • Medium: certificate validity period exceeds 4 hours or SSO tolerance exceeds 8 hours; more than one IdP (or a non-SAP-managed/“external” IdP) is trusted for the same subaccount, widening the forged-claim attack surface.
  • Reproducibility gate - flag before attempting the live probe: the connectivity-proxy leg only works from inside BTP’s own Cloud Foundry runtime for the target region (connectivityproxy.internal.cf.<region>.hana.ondemand.com is not internet-reachable). This is fully satisfiable within the customer’s own BTP org/space - not a SAP-managed-infrastructure dependency - provided the tester holds, or has pivoted to, a CF app-level foothold there.
  • A 401 from the live probe is evidence the underlying misconfiguration is not present (or the probe never reached the right identity claim) - report as inconclusive, not as a negative finding of “no risk.”

Options

Static analysis (offline, no live traffic) - over an extracted SCC config backup + on-prem USREXTID:

  • Classify each <subjectPattern> DN entry’s value as caller-controlled (${name}/${email}/${first_name}/${last_name}), stable (${user_uuid}), a literal, or a privileged literal (DDIC, SAP*, SAPSYS, EARLYWATCH, SOLMAN_BTC, SOLMAN_ADMIN, TMSADM, SAP_BASIS_USER, etc.).
  • Run the four-rule engine (Critical/Critical/High/High per Risk above) against every <subjectPattern>, plus config-level checks (empty <subjectPatterns> with PP-enabled mappings, over-long cert validity/SSO tolerance) and a cloud-side trust review of trustcfg_<uuid>.xml (external/multiple IdPs).
  • Concrete impersonation enumeration: cross-reference the (first) <subjectPattern>’s CN template against USREXTID TYPE=DN/TYPE=LD rows - extract each row’s CN, match it against the caller-controlled-or-literal verdict, and produce a roster of impersonatable BNAMEs, flagging any hit that is itself a privileged literal as trivially exploitable. TYPE=CA rows (trust an issuing CA rather than a specific mapping) widen the surface further via rule-based mapping but require a separate USR02 cross-link to fully enumerate - flag as advisory, not enumerated.
  • Manual equivalent: walk the SCC “Cloud To On-Premise → Access Control” UI’s subjectPattern config by hand; cross-reference SE16/SE16N on USREXTID on the on-prem side.

Live verification (real HTTP request, evidence-backed impersonation):

  • Supply a BTP access token for the target subaccount; resolve or create a PrincipalPropagation-authenticated destination pinned to the exact virtualHost:virtualPort the target SCC’s mapping already exposes (never point a destination at the on-prem internal IP directly - the connectivity proxy only routes by registered virtual host).
  • Fetch the destination’s resolved config (GET destination-configuration/v1/destinations/<name>) for its authTokens - typically Authorization: Bearer <user-jwt>, the actual PP assertion.
  • Issue a raw HTTP forward-proxy request (absolute-URI in the request line, no CONNECT) directly to the connectivity-proxy host:port (20003 HTTP / 20004 HTTPS), layering Proxy-Authorization, each destination authTokens[i] header, and (if multi-location) SAP-Connectivity-SCC-Location_ID.
  • Probe /sap/bc/ping: 200 = SCC minted a PP cert/token and the on-prem kernel accepted it; 401 = tunnel worked but the on-prem kernel rejected the identity (no USREXTID match, or SCC’s PP CA not trusted in STRUSTSSO2); 407 = the connectivity proxy itself rejected Proxy-Authorization - a proxy-layer failure distinct from the PP question.
  • On 200, additionally probe an OData catalog-service metadata endpoint and inspect response headers (sap-username, x-sap-user-name, sap-userid), a MYSAPSSO2 cookie, or the response body for the actual impersonated username.
  • Clean up any temporary destination regardless of outcome.
  • Proxy-auth caveat: Proxy-Authorization commonly needs a connectivity-service-bound token, not the caller’s bare BTP user JWT - the latter is “rarely” sufficient in production. Recipe when it fails: cf create-service connectivitycf bind-servicecf sshclient_credentials curl against the bound service’s own UAA.
  • Manual equivalent: configure a PrincipalPropagation destination in BTP Cockpit, cf ssh into a CF app on the target subaccount, curl /sap/bc/ping through the connectivity proxy by hand.
  • Reachability precondition: cf ssh -L 20003:<proxy-host>:<proxy-port> <app-name> through a CF app already controlled, or run the probe tooling itself as a CF workload in that org/space.

Mitigation

  • Add a <condition> to every <subjectPattern> scoping the rule to a specific, trusted cloud user group/IdP/email domain - never leave LOCAL-mode PP mappings with an unconditioned caller-controlled CN.
  • Prefer binding CN to ${user_uuid} (a stable, non-caller-forgeable identifier) over ${name}/${email}/${first_name}/${last_name}.
  • Never map a hardcoded privileged literal (DDIC, SAP*, etc.) as a <subjectPattern> CN value.
  • Lower certificateValidityPeriodInMins to 240 or less and ssoToleranceInHours to 8 or less unless an explicit operational reason justifies a wider window.
  • Restrict USREXTID TYPE=DN/TYPE=LD mappings so no privileged ABAP account is reachable via a CN a cloud IdP claim could plausibly produce; audit rule-based mapping (login/certificate_mapping_rulebased=1) with the same scrutiny.
  • Limit each BTP subaccount used for PP to a single, SAP-managed IdP (Identity Authentication Service) rather than multiple or externally-delegated IdPs.
  • Restrict destination_configuration.write scope tightly; monitor Destination-service create/delete pairs with very short lifetimes, especially for PrincipalPropagation/OnPremise-type destinations.
  • Restrict which CF apps/spaces can reach the BTP connectivity proxy segment at all; require connectivity-service-bound tokens as the only accepted Proxy-Authorization credential where policy allows.

Detection and Monitoring

  • On-prem ABAP: filter the Security Audit Log (SM20/RSAU_READ_LOG) for certificate-based logon events (X.509 class) arriving via the SCC’s system-certificate/RFC-gateway path, especially any resolving to a privileged account outside expected administrative windows.
  • On-prem ABAP: audit USREXTID (SE16/SE16N) periodically for TYPE=DN/TYPE=LD rows whose EXTID CN would resolve from a broadly-claimable cloud identity value (a common first/last name, a shared mailbox) mapped to a privileged BNAME.
  • On-prem ABAP: a /sap/bc/ping request immediately followed by a single OData catalog-service metadata GET, both authenticated via a freshly-minted PP certificate, is an unusual traffic shape for a legitimate application - worth a specific correlation rule.
  • SCC: review the Cloud Connector’s own Principal Propagation audit trail (Monitoring → Audit Log) for certificate-minting events tied to unexpected cloud-user claims, an unexpected/newly-created destination name, or unusually high mint volume from a single subaccount.
  • BTP/Destination service: audit-log create/delete events for short-lived, PrincipalPropagation-authenticated destinations - a destination created and deleted within seconds is a strong probing indicator, distinct from normal destination lifecycle management.
  • BTP/IdP: monitor for configuration changes that add “external”/self-registerable identity providers to a subaccount already used for PP-enabled SCC mappings.

References