Cloud Foundry Container SSH Access
Cloud Foundry exposes application containers through the Diego SSH subsystem. An authenticated user can open an interactive shell or run a single command inside a running app instance via cf ssh, or via a plain ssh client using a one-time authorization code. The session runs with the app’s own privileges - no host or root access - but exposes the app’s full runtime context.
That runtime context is the point. On SAP BTP, every bound service injects its credentials into the container as the VCAP_SERVICES environment variable: XSUAA client id/secret or x509 pair, HANA Cloud connection strings, Destination- and Connectivity-service credentials. VCAP_SERVICES is the single richest credential-harvest target on the platform, and this page covers the two ways to reach it - through the container, and around it.
The “around it” path matters more than the SSH path. The CF feature flag space_developer_env_var_visibility (default: enabled) lets any Space Developer read an app’s full environment over the Cloud Controller API without SSH being enabled at all. Disabling cf ssh does not stop credential harvesting. BTP customers cannot flip that flag themselves - it needs CF platform admin scope, which no customer holds (see Cloud Foundry: SAP BTP-Specific Attack Surface).
On SAP BTP, SSH is enabled by default down to space level, unlike vanilla CF where the operator picks the deployment-wide default. Effective access still requires deployment + space + app level all “on”, but the BTP default means only the app-level toggle typically stands between a Space Developer and a shell.
Any principal holding the Cloud Foundry Space Developer role - the routine permission for deploying an app, held by developers and CI/CD service users alike - can read every service credential reachable from that space, whether or not SSH is enabled. From inside a container an attacker can additionally:
- Extract OAuth tokens, client secrets, and certificates from bound services
- Inspect application source, runtime configuration, and staged build artifacts
- Execute arbitrary commands as the application runtime user
- Reach network endpoints the container can reach but the tester cannot, including bound backing services
- Tunnel to those backing services directly, turning an app foothold into a database session
Because Cloud Foundry treats the space as the primary trust boundary, this is not scoped to the one app compromised - it is every app and every bound service in the space.
cf ssh <APP-NAME>
$ env | grep VCAP_SERVICES
$ echo $VCAP_SERVICES | jq .
$ echo $VCAP_APPLICATION | jq .
VCAP_SERVICES.xsuaa[0].credentials contains url, clientid, clientsecret - or, for certificate-based bindings, an x509 cert/key pair instead of a secret. VCAP_APPLICATION leaks org/space GUIDs, app GUID, and route URIs, which feed straight into Cloud Controller API enumeration.
Harvested XSUAA credentials are used outside the container against the tenant’s /oauth/token endpoint - see XSUAA Token Abuse for what a client id/secret is worth once extracted.
cf env <APP-NAME>
# or directly against the API:
cf curl /v3/apps/$(cf app <APP-NAME> --guid)/env
Same VCAP_SERVICES content, no SSH involved, governed by space_developer_env_var_visibility rather than any SSH setting. Run this before concluding that a hardened cf disable-ssh posture protects an app’s credentials - it usually does not. The correct compensating control is minimizing what is in VCAP (certificate-based bindings, short-lived credentials), not the SSH flag state.
cf ssh-enabled <APP-NAME> # app-level state
cf space-ssh-allowed <SPACE> # space-level state (BTP default: allowed)
cf enable-ssh <APP-NAME> && cf restart <APP-NAME>
Enabling SSH requires a restart to take effect and is an audit-logged, user-visible change - coordinate before flipping it on a production app.
cf ssh-code # one-time authorization code
ssh -p 2222 cf:$(cf app <APP-NAME> --guid)/0@ssh.cf.<region>.hana.ondemand.com
Useful where the cf CLI is unavailable or where a raw SSH client is needed for tunneling/ProxyCommand chaining.
SAP publishes this itself as a legitimate developer workflow - cf ssh -L forwards a local port through the app container to a bound backing-service instance for direct DB tooling. The identical mechanism is available to anyone holding Space Developer plus SSH.
cf enable-ssh <APP-NAME> && cf restart <APP-NAME>
cf ssh -L 63306:<postgres-host-from-VCAP>:<postgres-port> <APP-NAME>
# separate terminal:
psql -h localhost -p 63306 -U <user-from-VCAP> -d <db-from-VCAP>
For HANA Cloud the tunnel is often unnecessary: HANA Cloud exposes one direct DB connection over port 443 on the public internet by default, so a harvested credential gives a working SQL session with no tunnel, VPN, or Cloud Connector involved.
hdbsql -n <host>:<port> -u <user> -p <password> -e # -e: TLS-only, required for HANA Cloud
Where the app’s own binding is read-scoped, minting a fresh, more privileged key against the same instance is a separate move - see Service Key & Credential Store Abuse.
Beyond env, the container holds the staged application as it actually runs:
$ cat /home/vcap/app/package.json # or pom.xml, mta.yaml remnants
$ ls -la /home/vcap/app/.profile.d/ # startup scripts, often hold exports
$ grep -rlE "(secret|password|clientsecret|api_key)" /home/vcap/app 2>/dev/null
$ cat /etc/cf-instance-credentials/* 2>/dev/null # instance identity cert/key, if present
Container-to-container networking is not available on SAP BTP CF, so do not spend session time scanning for sibling app containers - see the C2C dead end documented in Cloud Foundry: SAP BTP-Specific Attack Surface.
For the equivalent offline technique - pulling the staged filesystem without a live session at all - see cf download-droplet on the same page.
cf disallow-space-ssh <SPACE>on production spaces andcf disable-ssh <APP>per app - but do not treat this as sufficient:space_developer_env_var_visibilityindependently exposes the sameVCAP_SERVICESviacf env, and BTP customers cannot disable that flag.- Minimize what is in
VCAP_SERVICES: prefer certificate-based (x509) service bindings overclientsecretbindings, and short-lived credentials over standing ones. This is the control that actually holds when SSH controls do not. - Restrict Space Developer role assignment; separate development, test, and production into distinct spaces and subaccounts so a foothold in one does not reach another’s bound services.
- Segregate sensitive backing services (HANA Cloud, Credential Store) into dedicated, narrow-membership spaces.
- Scope bound DB users to least-privilege schemas; enforce TLS-only (
-e) HANA Cloud connections. - Never bake secrets into the build artifact - they survive into the container and the droplet regardless of SSH state.
- Rotate every credential reachable from a space where unauthorized SSH or API access is suspected; assume full
VCAP_SERVICESdisclosure.
- BTP Audit Log SSH session events, plus
cf enable-ssh/cf allow-space-sshconfiguration changes - treat enablement as an out-of-band monitored event. - In-container activity after
cf sshis not logged by the BTP Audit Log at all. The session’s start is visible; what happened inside it is not. - Direct SQL to HANA Cloud / PostgreSQL over a harvested credential or
cf ssh -Ltunnel is captured only by the database’s own audit mechanism (e.g. HANA’s SQL audit policies), never by the BTP platform log. Enable and centrally aggregate those separately. GET /v3/apps/:guid/envcalls across many apps from a single principal - thecf envharvesting signature, and the one that leaves a platform-side trace where SSH does not.- Monitor XSUAA token-issuance volume and source IPs for anomalies following any suspected VCAP leak.
- See BTP Audit Log Blind Spots for the full coverage and retention caveats governing all of the above.
- Accessing your apps with SSH | Cloud Foundry Docs
- SSH for Apps and Services | Cloud Foundry Docs
- Using feature flags with Cloud Foundry | Cloud Foundry Docs
- cloud_controller_ng issue #2271 – Space App Supporter env var access
- SAP Community – SAP BTP: PostgreSQL SSH Tunnel and SSH Tunneling Explained
- SAP Community – CF SSH: the tunnel to SAP-BTP: CF, HANA, Postgresql
- SAP Community – How to use an SSH tunnel with SCP Cloud Foundry backing-service
- SAP Community – Secure connection from HDBSQL to SAP HANA Cloud
- Related pages: Cloud Foundry: SAP BTP-Specific Attack Surface · Service Key Abuse · XSUAA Token Abuse
