HIGH xml external entitiesmutual tls

Xml External Entities with Mutual Tls

How Xml External Entities Manifests in Mutual Tls

XML External Entity (XXE) vulnerabilities in Mutual TLS (mTLS) environments exploit the trust relationship established between client and server certificates. When an API endpoint secured with mTLS processes XML input, the mutual authentication layer doesn't prevent XML parsers from resolving external entities, creating a dangerous attack surface.

In mTLS-secured APIs, attackers can leverage XXE through several attack vectors:

  • Internal network reconnaissance: An XXE payload can cause the server to resolve internal hostnames and IP addresses, mapping the internal network topology behind the mTLS gateway.
  • Service account credential exposure: If the mTLS client certificate has elevated privileges, XXE can trigger requests to internal services that expose credentials or configuration files.
  • Internal port scanning: XML parsers resolving external entities can perform blind port scanning of internal services accessible from the mTLS server.

Consider this vulnerable mTLS API endpoint in Go:

package main

import (
    "crypto/tls"
    "encoding/xml"
    "net/http"
)

func main() {
    // Mutual TLS configuration
    tlsConfig := &tls.Config{
        ClientAuth: tls.RequireAndVerifyClientCert,
        ClientCAs:  loadClientCAs(),
    }
    
    // Vulnerable XML processing
    http.HandleFunc("/api/data", func(w http.ResponseWriter, r *http.Request) {
        if r.TLS == nil || r.TLS.VerifiedChains == nil {
            http.Error(w, "mTLS required", http.StatusUnauthorized)
            return
        }
        
        var data Payload
        xml.NewDecoder(r.Body).Decode(&data) // No entity expansion disabled
        
        // Process data...
    })
    
    server := &http.Server{
        Addr:      ":443",
        TLSConfig: tlsConfig,
    }
    
    http.ListenAndServeTLS(":443", "server.crt", "server.key", nil)
}

type Payload struct {
    Data string `xml:"data"`
}

The vulnerability exists because the XML decoder processes external entities by default, even though the connection is secured with mTLS. An attacker with a valid client certificate can send:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
  <!ELEMENT foo ANY >
  <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/" >
]>
<data>&xxe;</data>

This payload would cause the server to make an HTTP request to the internal metadata service, potentially exposing cloud instance metadata. The mTLS layer only verifies the client certificate—it doesn't inspect XML content for malicious entities.

Mutual Tls-Specific Detection

Detecting XXE vulnerabilities in mTLS environments requires specialized scanning that can establish the mutual trust relationship while testing XML processing. Traditional scanners that don't support client certificates cannot reach these endpoints.

middleBrick's mTLS detection capabilities include:

  • Client certificate authentication: The scanner presents valid client certificates to establish mTLS connections before testing XML endpoints.
  • XML entity expansion testing: Active probing sends XXE payloads to detect whether external entities are processed.
  • Network boundary testing: The scanner attempts to resolve internal resources to identify internal network exposure.

Using middleBrick's CLI for mTLS XXE scanning:

npx middlebrick scan \
  --url https://api.example.com/v1/endpoint \
  --client-cert client.crt \
  --client-key client.key \
  --ca-cert ca.crt \
  --test xml-external-entities

The scanner automatically tests for XXE vulnerabilities by:

  1. Establishing an mTLS connection using the provided certificates
  2. Sending XML payloads with various entity definitions
  3. Monitoring for error responses, timeouts, or unexpected network requests
  4. Checking for SSRF indicators in the response

middleBrick's findings report includes severity ratings based on the potential impact:

SeverityRisk LevelTypical Impact
Critical90-100Remote code execution, internal network compromise
High70-89Internal network reconnaissance, credential exposure
Medium40-69Limited information disclosure
Low0-39No XXE vulnerability detected

The scanner also provides remediation guidance specific to mTLS environments, including secure XML parser configuration and network segmentation recommendations.

Mutual Tls-Specific Remediation

Securing XML processing in mTLS environments requires both XML parser hardening and network-level controls. The most effective approach combines secure XML parsing with mTLS-specific network restrictions.

Secure XML Parser Configuration

In Go, disable external entity processing:

package main

import (
    "crypto/tls"
    "encoding/xml"
    "io"
    "net/http"
    "golang.org/x/net/html/charset"
)

func secureXMLHandler(w http.ResponseWriter, r *http.Request) {
    if r.TLS == nil || r.TLS.VerifiedChains == nil {
        http.Error(w, "mTLS required", http.StatusUnauthorized)
        return
    }
    
    // Read body first
    body, err := io.ReadAll(r.Body)
    if err != nil {
        http.Error(w, "Invalid request", http.StatusBadRequest)
        return
    }
    
    // Create decoder with entity expansion disabled
    decoder := xml.NewDecoder(body)
    decoder.Entity = xml.HTMLEntity
    decoder.Strict = true
    
    // Prevent external entity resolution
    decoder.AutoClose = xml.HTMLAutoClose
    decoder.CharsetReader = charset.NewReaderLabel
    
    var data Payload
    err = decoder.Decode(&data)
    if err != nil {
        http.Error(w, "XML parsing error", http.StatusBadRequest)
        return
    }
    
    // Process data...
}

type Payload struct {
    Data string `xml:"data"`
}

Network-Level Controls

Implement network segmentation to limit the impact of potential XXE exploits:

// Network restrictions in mTLS configuration

tlsConfig := &tls.Config{
    ClientAuth: tls.RequireAndVerifyClientCert,
    ClientCAs:  loadClientCAs(),
    // Additional security
    MinVersion: tls.VersionTLS12,
    CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
    PreferServerCipherSuites: true,
}

// Create a restricted network client for any internal requests
server := &http.Server{
    Addr:      ":443",
    TLSConfig: tlsConfig,
    // Custom transport with restrictions
    Handler: &restrictedHandler{
        next: http.DefaultServeMux,
        // Block outbound requests from XML processing
        blockedHosts: map[string]bool{
            "169.254.169.254": true, // AWS metadata
            "metadata.google.internal": true, // GCP metadata
            "169.254.0.0/16": true, // Azure metadata range
        },
    },
}

// Custom handler that inspects requests
type restrictedHandler struct {
    next        http.Handler
    blockedHosts map[string]bool
}

func (h *restrictedHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    // Check if request is attempting to access blocked resources
    if h.isBlockedRequest(r) {
        http.Error(w, "Blocked", http.StatusForbidden)
        return
    }
    h.next.ServeHTTP(w, r)
}

func (h *restrictedHandler) isBlockedRequest(r *http.Request) bool {
    // Check host against blocked list
    if h.blockedHosts[r.Host] {
        return true
    }
    
    // Check for suspicious paths
    if r.URL.Path == "/latest/meta-data/" {
        return true
    }
    
    return false
}

Java Spring Boot Implementation

For Java applications using Spring Boot with mTLS:

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    @Bean
    public X509AuthenticationFilter x509AuthenticationFilter() {
        return new X509AuthenticationFilter();
    }
    
    @Bean
    public X509AuthenticationProvider x509AuthenticationProvider() {
        return new X509AuthenticationProvider();
    }
    
    @Bean
    public X509AuthenticationEntryPoint x509AuthenticationEntryPoint() {
        return new X509AuthenticationEntryPoint();
    }
    
    @Bean
    public XMLReader xmlReader() throws SAXException {
        XMLReader reader = XMLReaderFactory.createXMLReader();
        // Disable external entities
        reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
        reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
        return reader;
    }
    
    @Bean
    public DocumentBuilderFactory documentBuilderFactory() {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
        dbf.setExpandEntityReferences(false);
        dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
        dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
        return dbf;
    }
}

@RestController
@RequestMapping("/api")
public class ApiController {
    
    @PostMapping("/data")
    public ResponseEntity<String> processData(@RequestBody String xmlData) {
        // mTLS authentication handled by Spring Security
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (!(auth instanceof X509AuthenticationToken)) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("mTLS required");
        }
        
        try {
            // Secure XML processing
            DocumentBuilderFactory dbf = documentBuilderFactory();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(new InputSource(new StringReader(xmlData)));
            
            // Process document...
            return ResponseEntity.ok("Processed successfully");
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("XML processing error");
        }
    }
}

These remediation strategies ensure that even if an attacker obtains a valid mTLS client certificate, they cannot exploit XXE vulnerabilities to compromise internal systems or exfiltrate sensitive data.

Frequently Asked Questions

How does mTLS affect XXE vulnerability severity?
mTLS actually increases XXE severity because it establishes trust between client and server. An attacker with a valid client certificate can bypass authentication entirely and focus solely on XML processing vulnerabilities. The mutual trust means the server processes requests from authenticated clients without additional scrutiny, making XXE exploitation more straightforward.
Can middleBrick scan mTLS endpoints without client certificates?
No, middleBrick cannot scan mTLS endpoints without client certificates because the mutual authentication layer blocks unauthenticated requests. You must provide valid client certificates, client keys, and CA certificates to establish the mTLS connection before the scanner can test for XXE vulnerabilities and other security issues.