HIGH regex dosmutual tls

Regex Dos with Mutual Tls

How Regex DoS Manifests in Mutual TLS

Regular Expression Denial of Service (Regex DoS), also known as ReDoS, occurs when an attacker crafts input that causes a regex engine to consume exponential time during pattern matching. In Mutual TLS (mTLS) implementations, this vulnerability can manifest in several critical code paths that handle certificate validation, authentication headers, and certificate revocation checks.

The most common attack vector targets certificate subject fields during mTLS handshake validation. Consider a certificate validation function that uses regex to parse the Subject Alternative Name (SAN) field:

import re

def validate_san(san_string):
    pattern = r'DNS:([a-zA-Z0-9.-]+)'
    return bool(re.search(pattern, san_string))

# Vulnerable to ReDoS with input like:
vulnerable_input = 'DNS:a'*1000 + 'b'*1000 + 'c'*1000

This pattern contains nested quantifiers that can cause catastrophic backtracking. An attacker submitting a certificate with a crafted SAN field containing alternating character sequences can force the regex engine to evaluate billions of possible matches, effectively blocking the TLS handshake process.

Another mTLS-specific attack surface exists in certificate chain validation. Many implementations use regex to validate certificate chain formats or extract specific fields from PEM-encoded certificates:

func parseCertificatePEM(pemData string) ([]string, error) {
    pattern := `-----BEGIN CERTIFICATE-----(.*?)-----END CERTIFICATE-----`
    re := regexp.MustCompile(pattern)
    matches := re.FindAllStringSubmatch(pemData, -1)
    return matches, nil
}

// Vulnerable to input like:
vulnerablePEM = "-----BEGIN CERTIFICATE-----
" + "A"*10000 + "
" + "B"*10000 + "
" + "C"*10000

The non-greedy quantifier (.*?) combined with large input creates the same exponential time complexity. In mTLS contexts, this can prevent certificate chain validation, causing legitimate clients to be unable to establish secure connections.

Authentication middleware that validates mTLS client certificates often contains similar vulnerabilities. A common pattern uses regex to extract and validate certificate metadata:

function validateClientCert(certString) {
    const pattern = /CN=([^,]+),OU=([^,]+),O=([^,]+)/;
    const match = certString.match(pattern);
    if (!match) return false;
    
    // Vulnerable to ReDoS if match[1], match[2], or match[3] contain crafted input
    return match[1].length < 100 && match[2].length < 100;
}

An attacker can submit a certificate with carefully crafted Common Name (CN) or Organizational Unit (OU) fields that trigger exponential backtracking in the regex engine, causing the authentication check to hang indefinitely.

Mutual TLS-Specific Detection

Detecting Regex DoS in mTLS implementations requires both static analysis and runtime testing. Static analysis tools can identify vulnerable regex patterns, but mTLS-specific detection must account for certificate processing contexts.

Static analysis should flag these patterns in mTLS-related code:

# Look for vulnerable regex patterns in certificate processing code
rgrep -n '([a-zA-Z0-9.-]+)' *.py
rgrep -n '(.*?)' *.go
rgrep -n '([^,]+)' *.js

Focus on files containing keywords like "cert", "tls", "mTLS", "certificate", "handshake", and "auth". Pay special attention to functions that process certificate fields, validate certificate chains, or extract metadata from PEM data.

Runtime detection with middleBrick's API security scanner can identify active Regex DoS vulnerabilities in mTLS endpoints. The scanner tests certificate processing endpoints with crafted inputs designed to trigger exponential backtracking:

# Scan an mTLS API endpoint for Regex DoS vulnerabilities
middlebrick scan https://api.example.com/auth \
  --test-mtls \
  --cert client-cert.pem \
  --key client-key.pem

middleBrick specifically tests mTLS certificate processing endpoints by submitting certificates with crafted SAN fields, subject fields, and PEM data containing patterns that trigger ReDoS. The scanner measures response times and flags endpoints where processing takes significantly longer than baseline, indicating potential regex vulnerabilities.

Manual testing for mTLS-specific ReDoS involves creating test certificates with crafted fields:

# Create a test certificate with vulnerable SAN field
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem \
  -days 365 -nodes -subj "/CN=Test" \
  -addext "subjectAltName=DNS:$(python3 -c 'print("a"*1000 + "b"*1000 + "c"*1000)')"

Test the endpoint with this certificate and monitor for abnormal processing times or timeouts. A healthy mTLS implementation should process even crafted certificates in milliseconds, while vulnerable implementations may hang for seconds or minutes.

Network-level detection can identify ReDoS attacks in progress by monitoring for unusual patterns in TLS handshake timing. Sudden increases in handshake duration or repeated connection attempts with similar certificate patterns may indicate active exploitation attempts.

Mutual TLS-Specific Remediation

Remediating Regex DoS in mTLS implementations requires replacing vulnerable regex patterns with safer alternatives and implementing proper input validation. The most effective approach combines multiple strategies tailored to mTLS contexts.

First, replace vulnerable regex patterns with non-backtracking alternatives. For certificate field validation, use explicit character-by-character validation instead of regex:

def validate_san_safe(san_string):
    # Split on DNS: prefix and validate each component
    parts = san_string.split('DNS:')
    for part in parts[1:]:  # Skip first part (before first DNS:)
        if not part or len(part) > 253:  # DNS label max length
            return False
        labels = part.split('.')
        for label in labels:
            if not label or len(label) > 63:  # DNS label max length
                return False
            if not all(c.isalnum() or c in '-_' for c in label):
                return False
    return True

This approach eliminates regex entirely, using simple string operations with bounded iteration time. The validation runs in O(n) time regardless of input complexity, preventing ReDoS attacks.

For certificate chain validation, use streaming parsers instead of regex:

func parseCertificatePEMSafe(pemData string) ([]string, error) {
    const certStart = "-----BEGIN CERTIFICATE-----"
    const certEnd = "-----END CERTIFICATE-----"
    
    var certs []string
    scanner := bufio.NewScanner(strings.NewReader(pemData))
    
    var currentCert strings.Builder
    inCert := false
    
    for scanner.Scan() {
        line := scanner.Text()
        if line == certStart {
            inCert = true
            currentCert.Reset()
            currentCert.WriteString(line + "\n")
        } else if line == certEnd && inCert {
            currentCert.WriteString(line)
            certs = append(certs, currentCert.String())
            inCert = false
        } else if inCert {
            currentCert.WriteString(line + "\n")
        }
    }
    
    if inCert {
        return nil, errors.New("incomplete certificate")
    }
    
    return certs, nil
}

This streaming approach processes certificates line by line without regex, eliminating backtracking vulnerabilities. It also provides better error handling for malformed certificates.

Implement input length limits and timeouts for all certificate processing operations:

const MAX_CERTIFICATE_SIZE = 10240; // 10KB
const CERT_PROCESSING_TIMEOUT = 1000; // 1 second

function validateClientCertWithTimeout(certString) {
    return new Promise((resolve, reject) => {
        const timeoutId = setTimeout(() => {
            reject(new Error('Certificate processing timeout'));
        }, CERT_PROCESSING_TIMEOUT);
        
        try {
            const isValid = validateClientCertSafe(certString);
            clearTimeout(timeoutId);
            resolve(isValid);
        } catch (error) {
            clearTimeout(timeoutId);
            reject(error);
        }
    });
}

Timeouts prevent even vulnerable implementations from being completely blocked by ReDoS attacks. Combined with input size limits, this creates a defense-in-depth approach.

Consider using safe-regex libraries that analyze regex patterns for potential exponential runtime:

import safe_regex

# Check if a regex pattern is safe before using it
pattern = r'DNS:([a-zA-Z0-9.-]+)'
if not safe_regex.is_safe(pattern):
    raise ValueError('Unsafe regex pattern detected')

While safe-regex isn't perfect, it provides an additional layer of protection by flagging the most dangerous patterns before they can be deployed.

For mTLS implementations using third-party libraries, ensure you're using the latest versions, as many libraries have fixed known ReDoS vulnerabilities in certificate processing code. Regular dependency updates are crucial for maintaining security against these attacks.

Related CWEs: inputValidation

CWE IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

How can I test if my mTLS implementation is vulnerable to Regex DoS?

Use middleBrick's API security scanner to test your mTLS endpoints. The scanner submits crafted certificates with ReDoS-triggering patterns and measures processing times. Look for endpoints where processing takes significantly longer than normal (more than 2-3x baseline). You can also manually create test certificates with crafted SAN fields containing alternating character sequences and monitor handshake times using tools like Wireshark or tcpdump.

Are there specific regex patterns that are safe to use in mTLS certificate processing?

Yes, use regex patterns with atomic grouping, possessive quantifiers, or limited repetition that prevent backtracking. For example, use (?>...) atomic groups in Perl-compatible regex engines, or limit quantifiers with specific bounds like {0,10} instead of +. However, the safest approach is to avoid regex entirely for certificate processing and use explicit string validation or streaming parsers that operate in O(n) time regardless of input complexity.