SOAP
1. Basic Concepts of SOAP
Contrary to its name, SOAP (Simple Object Access Protocol) is not a simple protocol. It is platform and language independent, offering flexibility to operate over various protocols like HTTP, SMTP, and TCP. The core of SOAP is that it uses XML (eXtensible Markup Language) to define messages.
SOAP Message Structure
All SOAP messages follow a standardized XML structure:
- Envelope (Required): The top-level element of a SOAP message, indicating the start and end of the message. It defines the XML namespace to identify the message as a SOAP message.
- Header (Optional): Contains additional information not directly related to the message body. It’s primarily used for handling metadata such as authentication tokens, transaction IDs, and routing information. The header allows for adding various functionalities to the message processing, forming the basis for powerful security features when combined with standards like WS-Security.
- Body (Required): Contains the actual data to be transmitted, namely the name and parameter information of the remote procedure call (RPC) to be invoked. The core content of the service request is located here.
- Fault (Optional): An element used when an error occurs during message processing. It is included within the Body element and conveys detailed information such as the error code, description, and the location of the error to the client.
SOAP Message Example
The following is a hypothetical SOAP message example requesting the price of a specific stock. This example clearly shows how each component is used.
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
xmlns:m="http://www.example.org/stock">
<soap:Header>
<m:TransactionID>5</m:TransactionID>
</soap:Header>
<soap:Body>
<m:GetStockPrice>
<m:StockName>GOOG</m:StockName>
</m:GetStockPrice>
</soap:Body>
</soap:Envelope>
soap:Envelope
: The root element of the message, defining two namespaces,soap
andm
.soap:Header
: Contains metadata calledTransactionID
. This ID can be used for logging or transaction tracking.soap:Body
: Contains the actual content the client is requesting from the server. Here, it’s calling an operation namedGetStockPrice
and passing ‘GOOG’ as theStockName
parameter.
As you can see, SOAP messages have a clear and standardized structure, allowing for the systematic representation of complex requests.
WSDL (Web Services Description Language)
When discussing SOAP, WSDL is indispensable. WSDL is an XML-based specification that describes everything about a web service. It details the functions (Operations) provided by the service, the message formats required for each function, data types, and the endpoint addresses for accessing the service. Clients can refer to this WSDL file to clearly understand how to communicate with the server, enabling strict contract-first development.
2. SOAP vs. REST: A Comparison of Key Differences
SOAP and REST are two different approaches to implementing web services, each with distinct advantages and disadvantages.
Category | SOAP (Simple Object Access Protocol) | REST (Representational State Transfer) |
---|---|---|
Paradigm | Protocol | Architectural Style |
Data Format | XML only | Supports various formats like JSON, XML, TEXT, HTML |
Transport Protocol | Supports various protocols like HTTP, SMTP, TCP (independent) | Primarily relies on HTTP |
State Management | Can be stateful or stateless | Adheres to the principle of being stateless |
Performance | Relatively heavy and slow due to XML parsing and strict structure | Fast performance due to lightweight messages and caching |
Security | Provides robust security features like message-level encryption and signatures through the WS-Security standard | Relies on transport-layer security via HTTPS. Application-level security implemented with OAuth, JWT, etc. |
Scalability | Horizontal scaling can be difficult with stateful approaches | Horizontal scaling is easy due to its stateless nature |
Specification | Defines strict contracts through an official specification called WSDL | APIs can be described using the OpenAPI Specification (Swagger), but it’s not mandatory |
In summary, SOAP is suitable for enterprise environments such as finance, government, and healthcare, where a high level of security, reliability, and transaction integrity must be guaranteed through its standardized and strict structure. On the other hand, REST is widely used in mobile apps, public APIs, and microservices architectures, leveraging its flexibility, simplicity, and fast performance.
3. SOAP Security Vulnerabilities: Attack Vectors and Countermeasures
Despite SOAP’s strong security features, its XML-based nature and complexity can expose it to various security vulnerabilities. Red teams and security engineers should be familiar with the following attack vectors.
1. XML External Entity (XXE) Injection
This is one of the most critical SOAP vulnerabilities. It occurs when the XML parser is configured to process external entities. An attacker can send a SOAP request containing a maliciously crafted XML entity to read local files on the server, conduct Server-Side Request Forgery (SSRF) attacks on the internal network, or even lead to remote code execution.
Attack Example (File Exfiltration):
The attacker includes a request to load an external Document Type Definition (DTD) using the SYSTEM
keyword. The example below is an attempt to read the contents of the /etc/passwd
file.
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<m:GetUserDetails>
<m:UserId>&xxe;</m:UserId>
</m:GetUserDetails>
</soap:Body>
</soap:Envelope>
If the server’s XML parser processes this request as is, the &xxe;
entity will be replaced with the content of the /etc/passwd
file, which could then be included in the response or exposed in some other way.
Countermeasures:
- Disable External Entity Processing: The most effective solution is to disable the processing of external entities (including DTDs) in the XML parser you are using.
- Input Validation: Always strictly validate and filter XML data received from untrusted sources.
2. XML Bomb (Billion Laughs Attack)
This is a type of Denial of Service (DoS) attack that utilizes recursive entity expansion. The attacker defines nested entities within a small XML request. As the parser expands these entities, memory usage increases exponentially, eventually exhausting the server’s resources and causing the service to crash.
Attack Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<message>&lol9;</message>
</soap:Body>
</soap:Envelope>
The &lol9;
in this request ultimately expands to one billion “lol” strings, occupying several gigabytes of memory.
Countermeasures:
- Limit Entity Expansion: Limit the depth and number of entity expansions in the XML parser.
- Resource Limiting: Limit the memory and CPU usage that individual requests can consume to minimize the impact of DoS attacks.
- Use an API Gateway: Use an API gateway to validate message size, structure, etc., and block malicious requests beforehand.
3. WS-Security Misconfiguration
WS-Security is a powerful standard that provides message integrity (signing), confidentiality (encryption), and authentication. However, its complexity can easily lead to configuration errors. For example, a weak encryption algorithm might be used, signature verification might not be properly performed, or only certain headers might be encrypted while other important parts are left in plaintext.
Attack Vectors:
- Replay Attack: An attacker intercepts a signed message and retransmits it to perform unauthorized actions. This occurs when elements like
Timestamp
orNonce
are not properly validated. - Signature Wrapping: The attacker leaves the signed
Body
part intact but adds a maliciousBody
. The original signedBody
is moved elsewhere, causing the parser to validate the signature as valid but process the maliciousBody
.
Countermeasures:
- Adhere to and Update Standards: Accurately understand and implement the WS-Security standard, and use up-to-date cryptographic suites with no known vulnerabilities.
- Strict Validation: Thoroughly validate the uniqueness and validity period of messages using
Timestamp
,Nonce
, etc., to prevent replay attacks. - Structural Validation: When verifying signatures, it’s crucial to confirm that the location and structure of the signed element match expectations to block signature wrapping attacks.
Python SOAP Client Example (Zeep library)
To help understand how a real SOAP request is made, here is a simple client code using Python’s zeep
library.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import zeep
# Public calculator WSDL service URL
wsdl_url = 'http://www.dneonline.com/calculator.asmx?WSDL'
try:
# 1. Create a client object using the WSDL URL
client = zeep.Client(wsdl=wsdl_url)
# 2. Call a service operation (Add)
# Uses parameters intA and intB as per the WSDL specification
result = client.service.Add(intA=10, intB=20)
# 3. Print the result
print(f"10 + 20 = {result}")
# Call the Divide operation
result_div = client.service.Divide(intA=20, intB=10)
print(f"20 / 10 = {result_div}")
except Exception as e:
print(f"An error occurred: {e}")
This code analyzes the WSDL to identify available services (like Add
, Divide
, etc.) and sends a request in the appropriate format to get the result. From a security testing perspective, one could intercept such a request with a proxy tool (e.g., Burp Suite) and inject payloads to test for the vulnerabilities mentioned above.
1. SOAP의 기본 개념
SOAP은 그 이름과 달리 그리 간단하지 않은 프로토콜입니다. 특정 플랫폼이나 언어에 종속되지 않고, 주로 HTTP, SMTP, TCP 등 다양한 프로토콜 위에서 동작할 수 있는 유연성을 가집니다. SOAP의 핵심은 XML(eXtensible Markup Language)을 사용하여 메시지를 정의한다는 점입니다.
SOAP 메시지 구조
모든 SOAP 메시지는 다음과 같은 표준화된 XML 구조를 따릅니다.
- Envelope (필수): SOAP 메시지의 최상위 요소로, 메시지의 시작과 끝을 알립니다. XML 네임스페이스를 정의하여 메시지를 SOAP 메시지로 식별합니다.
- Header (선택): 메시지 본문과 직접적인 관련이 없는 부가 정보를 담습니다. 주로 인증 토큰, 트랜잭션 ID, 라우팅 정보 등과 같은 메타데이터를 처리하는 데 사용됩니다. 헤더를 통해 메시지 처리 과정에 다양한 기능을 추가할 수 있으며, 이는 WS-Security와 같은 표준과 결합하여 강력한 보안 기능을 제공하는 기반이 됩니다.
- Body (필수): 실제 전송될 데이터, 즉 호출하려는 원격 프로시저(RPC)의 이름과 매개변수 정보를 담고 있습니다. 서비스 요청의 핵심 내용이 바로 여기에 위치합니다.
- Fault (선택): 메시지 처리 중 오류가 발생했을 때 사용되는 요소입니다. Body 요소 내에 포함되며, 오류 코드, 설명, 오류 발생 위치 등의 상세 정보를 클라이언트에게 전달합니다.
SOAP 메시지 예시
다음은 특정 주식의 가격을 요청하는 가상의 SOAP 메시지 예시입니다. 이 예시를 통해 각 구성요소가 어떻게 사용되는지 명확히 알 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
xmlns:m="http://www.example.org/stock">
<soap:Header>
<m:TransactionID>5</m:TransactionID>
</soap:Header>
<soap:Body>
<m:GetStockPrice>
<m:StockName>GOOG</m:StockName>
</m:GetStockPrice>
</soap:Body>
</soap:Envelope>
soap:Envelope
: 메시지의 루트 요소로,soap
와m
이라는 두 개의 네임스페이스를 정의합니다.soap:Header
:TransactionID
라는 메타데이터를 포함합니다. 이 ID는 로깅이나 트랜잭션 추적에 사용될 수 있습니다.soap:Body
: 클라이언트가 서버에 요청하는 실제 내용을 담고 있습니다. 여기서는GetStockPrice
라는 작업을 호출하고 있으며,StockName
이라는 매개변수로 ‘GOOG’를 전달하고 있습니다.
이처럼 SOAP 메시지는 그 구조가 명확하고 표준화되어 있어, 복잡한 요청도 체계적으로 표현할 수 있습니다.
WSDL (Web Services Description Language)
SOAP을 이야기할 때 WSDL을 빼놓을 수 없습니다. WSDL은 웹 서비스의 모든 것을 설명하는 XML 기반의 명세서입니다. 서비스가 제공하는 기능(Operations), 각 기능에 필요한 메시지 형식, 데이터 타입, 그리고 서비스에 접근할 수 있는 엔드포인트(Endpoint) 주소 등이 상세하게 정의되어 있습니다. 클라이언트는 이 WSDL 파일을 참조하여 서버와 어떻게 통신해야 하는지 명확하게 알 수 있으며, 이를 통해 엄격한 계약 기반(Contract-first) 개발이 가능해집니다.
2. SOAP vs. REST: 핵심 차이점 비교
SOAP과 REST는 웹 서비스를 구현하는 두 가지 다른 접근 방식이며, 각각의 장단점이 뚜렷합니다.
구분 | SOAP (Simple Object Access Protocol) | REST (Representational State Transfer) |
---|---|---|
패러다임 | 프로토콜(Protocol) | 아키텍처 스타일(Architectural Style) |
데이터 형식 | XML만 사용 | JSON, XML, TEXT, HTML 등 다양한 형식 지원 |
전송 프로토콜 | HTTP, SMTP, TCP 등 다양한 프로토콜 지원 (독립적) | 주로 HTTP에 의존 |
상태 관리 | 상태 유지(Stateful) 또는 상태 비유지(Stateless) 모두 가능 | 상태 비유지(Stateless)를 원칙으로 함 |
성능 | XML 파싱, 엄격한 구조로 인해 상대적으로 무겁고 느림 | 메시지가 가볍고 캐싱을 활용하여 빠른 성능 |
보안 | WS-Security라는 표준을 통해 메시지 레벨 암호화, 서명 등 강력한 보안 기능 제공 | HTTPS를 통한 전송 계층 보안에 의존. OAuth, JWT 등으로 애플리케이션 레벨 보안 구현 |
확장성 | 상태 유지(Stateful) 방식으로 인해 수평적 확장이 어려울 수 있음 | 상태 비유지(Stateless) 방식으로 인해 수평적 확장이 용이함 |
명세 | WSDL이라는 공식 명세를 통해 엄격한 계약 정의 | OpenAPI Specification (Swagger) 등으로 API를 기술하지만, 필수는 아님 |
요약하자면, SOAP은 표준화되고 엄격한 구조를 통해 높은 수준의 보안, 신뢰성, 트랜잭션이 보장되어야 하는 금융, 정부, 의료 등 엔터프라이즈 환경에 적합합니다. 반면 REST는 유연성, 단순함, 빠른 성능을 바탕으로 모바일 앱, 공개 API, 마이크로서비스 아키텍처 등에서 널리 사용됩니다.
3. SOAP 보안 취약점: 공격 벡터 및 대응 방안
SOAP의 강력한 보안 기능에도 불구하고, XML 기반이라는 특성과 복잡성으로 인해 다양한 보안 취약점에 노출될 수 있습니다. 레드팀 및 보안 엔지니어는 다음과 같은 공격 벡터를 숙지하고 있어야 합니다.
1. XML 외부 개체 주입 (XML External Entity - XXE)
가장 치명적인 SOAP 취약점 중 하나입니다. XML 파서가 외부 개체(External Entity)를 처리하도록 설정되어 있을 때 발생합니다. 공격자는 악의적으로 조작된 XML 개체를 포함하는 SOAP 요청을 보내 서버의 로컬 파일을 읽거나, 내부 네트워크로의 SSRF(Server-Side Request Forgery) 공격을 감행하거나, 심지어 원격 코드 실행으로까지 이어질 수 있습니다.
공격 예시 (파일 탈취):
공격자는 SYSTEM
키워드를 사용하여 외부 DTD(Document Type Definition)를 로드하도록 요청에 포함시킵니다. 아래 예시는 /etc/passwd
파일의 내용을 읽어오려는 시도입니다.
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<m:GetUserDetails>
<m:UserId>&xxe;</m:UserId>
</m:GetUserDetails>
</soap:Body>
</soap:Envelope>
만약 서버의 XML 파서가 이 요청을 그대로 처리한다면, &xxe;
엔티티는 /etc/passwd
파일의 내용으로 치환되어 응답에 포함되거나 다른 방식으로 노출될 수 있습니다.
대응 방안:
- 외부 개체 처리 비활성화: 사용하는 XML 파서에서 외부 개체(DTD 포함) 처리를 비활성화하는 것이 가장 확실한 해결책입니다.
- 입력 값 검증: 신뢰할 수 없는 소스로부터 받은 XML 데이터는 항상 엄격하게 검증하고 필터링해야 합니다.
2. XML 폭탄 (Billion Laughs Attack)
서비스 거부(Denial of Service - DoS) 공격의 일종으로, 재귀적인 엔티티 확장을 이용합니다. 공격자는 작은 크기의 XML 요청 내에 여러 단계로 중첩된 엔티티를 정의합니다. 파서가 이 엔티티들을 확장하는 과정에서 메모리 사용량이 기하급수적으로 증가하여 결국 서버의 리소스를 고갈시키고 서비스를 마비시킵니다.
공격 예시:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<message>&lol9;</message>
</soap:Body>
</soap:Envelope>
이 요청의 &lol9;
는 최종적으로 10억 개의 “lol” 문자열로 확장되어 수 기가바이트의 메모리를 점유하게 됩니다.
대응 방안:
- 엔티티 확장 제한: XML 파서에서 엔티티 확장의 깊이와 개수를 제한합니다.
- 리소스 제한: 개별 요청이 사용할 수 있는 메모리와 CPU 사용량을 제한하여 DoS 공격의 영향을 최소화합니다.
- API 게이트웨이 활용: API 게이트웨이를 사용하여 메시지 크기, 구조 등을 사전에 검증하고 유해한 요청을 차단합니다.
3. WS-Security 설정 오류
WS-Security는 메시지 무결성(서명), 기밀성(암호화), 인증을 제공하는 강력한 표준이지만, 복잡성으로 인해 설정 오류가 발생하기 쉽습니다. 예를 들어, 암호화 알고리즘이 취약하거나, 서명 검증이 제대로 이루어지지 않거나, 특정 헤더만 암호화하고 중요한 다른 부분은 평문으로 두는 등의 실수가 발생할 수 있습니다.
공격 벡터:
- 메시지 재전송 공격(Replay Attack): 서명된 메시지를 탈취하여 그대로 재전송함으로써 비인가된 작업을 수행합니다.
Timestamp
나Nonce
와 같은 요소가 제대로 검증되지 않을 때 발생합니다. - 서명 래핑(Signature Wrapping): 서명된
Body
부분을 그대로 둔 채, 악의적인Body
를 추가하고 원래의 서명된Body
는 다른 곳으로 옮겨 파서가 서명은 유효하다고 판단하지만 실제로는 악의적인Body
를 처리하게 만드는 공격입니다.
대응 방안:
- 표준 준수 및 최신화: WS-Security 표준을 정확히 이해하고 구현하며, 알려진 취약점이 없는 최신 암호화 스위트를 사용합니다.
- 엄격한 검증:
Timestamp
,Nonce
등을 사용하여 메시지의 유일성과 유효 기간을 철저히 검증하여 재전송 공격을 방지합니다. - 구조적 유효성 검사: 서명 검증 시, 서명된 요소의 위치와 구조가 예상과 일치하는지 반드시 확인하여 서명 래핑 공격을 차단해야 합니다.
Python SOAP 클라이언트 예시 (Zeep 라이브러리)
실제 SOAP 요청이 어떻게 이루어지는지 이해를 돕기 위해 Python의 zeep
라이브러리를 사용한 간단한 클라이언트 코드를 소개합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import zeep
# 공개 계산기 WSDL 서비스 URL
wsdl_url = 'http://www.dneonline.com/calculator.asmx?WSDL'
try:
# 1. WSDL URL을 사용하여 클라이언트 객체 생성
client = zeep.Client(wsdl=wsdl_url)
# 2. 서비스가 제공하는 오퍼레이션 호출 (Add)
# WSDL 명세에 따라 intA와 intB라는 매개변수를 사용
result = client.service.Add(intA=10, intB=20)
# 3. 결과 출력
print(f"10 + 20 = {result}")
# Divide 오퍼레이션 호출
result_div = client.service.Divide(intA=20, intB=10)
print(f"20 / 10 = {result_div}")
except Exception as e:
print(f"An error occurred: {e}")
이 코드는 WSDL을 분석하여 사용 가능한 서비스(Add
, Divide
등)를 파악하고, 해당 서비스에 맞는 형식으로 요청을 보내 결과를 받아옵니다. 보안 테스팅 관점에서는 이러한 요청을 프록시 도구(예: Burp Suite)로 가로채 위에서 언급한 취약점을 테스트하기 위한 페이로드를 삽입하는 방식으로 접근할 수 있습니다.