A practical reading of the OWASP Web Service Security Cheat Sheet for SOAP services and JSON APIs. Prove who is calling, allow only the action they should take, reject a body you did not define, and refuse to be drowned in data.
Primary source: OWASP Web Service Security Cheat Sheet. For HTTP APIs, read it alongside the OWASP API Security Top 10.
A valid token tells you who the caller is. It does not mean they may see this record.
Channel and caller
| Topic | Key points |
|---|---|
| Transport | Use TLS for every authenticated or sensitive call, including service-to-service. Encrypting the body does not replace TLS. |
| Server certificate | Reject certificates that are expired, untrusted, or whose hostname does not match. Do not disable verification in client libraries. |
| Client authentication | Prefer mutual TLS or a signed OAuth 2.0 / OpenID Connect token. HTTP Basic belongs only on TLS, and it is a weak default. |
| Token checks | Validate the signature, issuer, audience and expiry. A token that merely parses is not authenticated. |
| Replay | Prefer short-lived tokens. A captured request must not stay valid for days. Rotate a client secret when staff leave or that client is compromised. |
| Secrets | Do not put API keys or passwords in the query string. They end up in logs, history and the Referer header. |
| Authorisation | Check the action and the specific object on every request. A valid login is not permission to read another customer's record. |
| Sensitive changes | Re-check identity before a password, email, payment or delivery-address change. |
| Admin surface | Keep management operations off the API a normal customer token can call. |
| Logging | Record the caller, the operation and the result. Do not log passwords, API keys or the raw token. |
The message
| Topic | Key points |
|---|---|
| Schema | SOAP: validate against the XSD before use. REST: validate against a JSON schema. Cap length and allow-list fixed fields. |
| Content type | Client and server must agree the encoding. Reject a body whose Content-Type does not match what you parse. |
| XML parser | Disable external entities and DTDs. Cap entity expansion, recursion, element-name length and document size. |
| JSON parser | Cap nesting depth and document size. A deeply nested object is the same denial-of-service risk as an XML bomb. |
| Integrity | TLS protects the hop. Use an XML signature or a signed token when you must prove who wrote the message. |
| Fields at rest | If a value must stay secret after you store it, encrypt that field. Transport encryption ends when the request ends. |
| Output | If a client renders the response as HTML, encode for that context. JSON dropped into innerHTML is cross-site scripting. |
| Attachments | Scan uploads before they are stored. Do not trust the filename, and do not write the file using the path the client sent. |
| Old operations | Retired WSDL methods and unused HTTP verbs are still in scope. Remove them, or give them the same checks as the live ones. |
| Fail closed | If the schema check, the signature check or the authorisation check errors, deny the request. Do not continue on a parser warning. |
| Limits | Cap message size, concurrent connections and request rate. An unbounded body is a denial-of-service. |
| Errors | Return a generic fault to the caller. Keep stack traces, SQL and file paths in server logs only. |
What a test should show
- A caller with a valid token for object A cannot read or change object B.
- Certificate checks are on, including in service-to-service clients.
- Oversized, deeply nested and wrong-type bodies are rejected before business logic runs.
- The XML parser does not resolve external entities.
- Admin operations are not available on the customer API.
- Faults returned to the client do not include stack traces, queries or file paths.
Ready to strengthen your security?
Talk to our consultants about your penetration testing requirements, or get a fast, transparent quote.