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

Exposed SOAP Services

Description

BTP applications and Integration Suite iFlows reach SOAP web services - on the internet, or on-premise via Cloud Connector - through HTTP-type destinations pointing at a SOAP endpoint. SOAP backends carry two testable weaknesses that REST destinations do not: a WSDL that self-describes every operation, type, and binding an attacker could call, and a long tail of SOAP-specific parsing behavior (XXE, SOAPAction spoofing, WS-Security handling) in the backend stack.

This page covers what to do once you have reached, or can reach, a SOAP destination. The destination inventory and triage that gets you here is on BTP Destinations; the credential-disclosure and on-prem-pivot mechanics are on Destination Service Abuse.

Risk

An attacker who can invoke a SOAP destination inherits whatever the destination’s stored credential and the backend’s authorization allow. Where the destination uses NoAuthentication, or where the backend trusts the destination’s technical user broadly, this is direct unauthorized access to backend data or privileged operations - and where proxyType: OnPremise, it is a cloud-to-on-prem pivot. An openly readable WSDL hands the attacker the full operation catalog to target, including operations the front-end application never intended to expose.

Options

Locate and pull the WSDL

SOAP endpoints conventionally expose their contract at ?wsdl (or ?singleWsdl for a self-contained one on ABAP/.NET stacks):

curl -sk "https://<soap-endpoint>/path/to/service?wsdl" -o service.wsdl
curl -sk "https://<soap-endpoint>/path/to/service?singleWsdl" -o service.wsdl   # inlined imports

If the destination is OnPremise, the request goes through the app/iFlow that fronts it - reach it from the app’s own public route or, in Integration Suite, via a Request-Reply/SOAP-adapter iFlow (see Integration Suite Groovy Scripting for turning an iFlow into an authenticated internal proxy).

Enumerate operations from the WSDL

# operations and their SOAPAction values:
grep -oE '<(wsdl:)?operation name="[^"]+"' service.wsdl
grep -oE 'soapAction="[^"]*"' service.wsdl
# service endpoint(s) the WSDL advertises:
grep -oE 'location="[^"]+"' service.wsdl

Tools that consume the WSDL and generate skeleton requests: wsdl2py/zeep (Python), SoapUI, or Burp’s WSDLer. Map the operation list against what the front-end app actually uses - the gap (admin/maintenance/debug operations reachable but never called by the UI) is the finding.

Test authentication and SOAPAction handling

# Does the operation require auth at all, or does the destination's stored credential carry it?
curl -sk -X POST "https://<endpoint>" \
  -H "Content-Type: text/xml; charset=utf-8" \
  -H "SOAPAction: <ActionFromWSDL>" \
  --data @request.xml
  • NoAuthentication destination -> the call reaches the backend with no credential; you inherit whatever the backend grants anonymously.
  • SOAPAction spoofing -> some stacks route on the SOAPAction header rather than the body element; try invoking a privileged operation’s action against an endpoint that gates only the expected one.
  • WS-Security bypass -> where the backend expects a <wsse:Security> header, test whether omitting it, or supplying an unsigned/empty token, is accepted.

SOAP-specific injection

SOAP bodies are XML - the backend XML parser is the target:

<!-- XXE probe, if the backend parser resolves external entities -->
<?xml version="1.0"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<soapenv:Envelope ...><soapenv:Body>
  <ns:someOperation><param>&xxe;</param></ns:someOperation>
</soapenv:Body></soapenv:Envelope>

Also test SQL/command injection through operation parameters, and XML bomb / billion-laughs for DoS resilience (coordinate before running DoS-class payloads on a production backend). Blind XXE / out-of-band exfil is especially relevant here because the SOAP call originates from BTP’s IP space or the on-prem network - an OOB callback confirms reachability from inside.

Mitigation

  • Enforce strong authentication on all SOAP destinations - OAuth2SAMLBearerAssertion or OAuth2ClientCredentials. Never NoAuthentication!
  • Least-privilege the destination’s technical user to the specific operations the app needs, not the backend’s full SOAP surface.
  • Require authentication for WSDL retrieval and disable ?wsdl/?singleWsdl exposure in production where possible.
  • Restrict Cloud Connector access to only the required host, port, and (where supported) URL paths, so an OnPremise SOAP destination cannot reach beyond the intended service.
  • Harden the backend XML parser: disable external-entity resolution (XXE), enforce WS-Security signature validation, and validate against the schema.
  • Monitor destination usage via BTP Audit Logs and restrict which applications may consume each destination.

Detection and Monitoring

  • Backend web-service logs for calls to operations the front-end application never invokes, or for SOAPAction values inconsistent with the request body.
  • WSDL-retrieval requests (?wsdl/?singleWsdl) from unexpected sources.
  • XML parser errors, DTD/external-entity resolution attempts, and outbound connections from the backend following a SOAP request (OOB XXE signature).
  • Cloud Connector access logs - note the SCC default audit level does not record successful accesses; raise it to “All” on sensitive backends (see BTP Audit Log Blind Spots).

References