HIGH ssrfchimutual tls

Ssrf in Chi with Mutual Tls

Ssrf in Chi with Mutual Tls — how this specific combination creates or exposes the vulnerability

Server-Side Request Forgery (SSRF) in Chi with Mutual TLS (mTLS) involves a scenario where an authenticated service or client can cause the server to make unintended requests to internal or external endpoints, even though mTLS is in place. mTLS ensures both the client and server present valid certificates, which typically restricts who can initiate a connection. However, SSRF can still manifest when the server-side application acts as a proxy or when client certificates are obtained and misused within the application logic.

In Chi, this often occurs when developers build custom HTTP clients that forward requests based on user input without adequate validation. For example, if an endpoint accepts a URL parameter and uses a http.Client with a custom Transport that includes a client certificate, an attacker might supply an internal address like http://169.254.169.254/latest/meta-data/ (AWS metadata service) or an internal Kubernetes service. Even with mTLS protecting the perimeter, the server’s outbound request may not enforce the same strict network segmentation, allowing the SSRF to reach internal services that trust the server’s certificate.

The risk is amplified when the server’s mTLS configuration does not restrict outbound destinations. The server certificate is trusted by internal services, so requests originating from the server are accepted. If the application does not validate the target host, port, or scheme, an attacker can pivot from the exposed endpoint to internal systems, bypassing network-level mTLS restrictions that were designed only for inbound connections. This combination of mTLS for authentication and SSRF for request manipulation creates a path where the server’s trusted identity is leveraged to access protected internal resources.

Real-world patterns include APIs that accept a target host for health checks or webhook delivery, where the developer assumes mTLS is sufficient. In Chi, a route might use middleware to load client certificates dynamically, but if the target URL is user-supplied without host allowlisting, the mTLS protection does not prevent the malicious request from reaching unintended endpoints. Tools like middleBrick can detect such misconfigurations by scanning the unauthenticated attack surface and identifying endpoints that accept URLs without proper validation, even when mTLS is present.

Mutual Tls-Specific Remediation in Chi — concrete code fixes

Remediation focuses on strict input validation, network controls, and certificate usage. Below are concrete examples using Chi and Go’s http.Transport to enforce safe outbound requests while preserving mTLS.

1. Allowlist Hosts in HTTP Client

Create a custom RoundTripper that validates the request URL against an allowlist before proceeding. This prevents SSRF by ensuring only approved domains or IPs are reachable.

import (
    "crypto/tls"
    "net/http"
    "strings"
)

func allowlistTransport(allowedHosts []string, baseTransport http.RoundTripper) http.RoundTripper {
    return &allowlistRoundTripper{
        allowedHosts: allowedHosts,
        base:         baseTransport,
    }
}

type allowlistRoundTripper struct {
    allowedHosts []string
    base         http.RoundTripper
}

func (t *allowlistRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
    host := req.URL.Hostname()
    for _, allowed := range t.allowedHosts {
        if host == allowed {
            return t.base.RoundTrip(req)
        }
    }
    return nil, &urlError{err: "host not allowed", url: req.URL.String()}
}

// Usage in Chi route
func healthCheckHandler(client *http.Client) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // Use client with allowlist transport
        resp, err := client.Get("https://" + r.URL.Query().Get("host"))
        if err != nil {
            http.Error(w, err.Error(), http.StatusBadRequest)
            return
        }
        defer resp.Body.Close()
        w.WriteHeader(resp.StatusCode)
    }
}

2. Enforce mTLS with Restricted Certificates

Configure the server and client to use specific certificates and verify peer identities strictly. In Chi, you can set up a TLS configuration that pins client certificates and disables insecure options.

func secureClientCert(certFile, keyFile, caCert string) (*http.Client, error) {
    cert, err := tls.LoadX509KeyPair(certFile, keyFile)
    if err != nil {
        return nil, err
    }
    rootCAs, err := os.ReadFile(caCert)
    if err != nil {
        return nil, err
    }
    certPool := x509.NewCertPool()
    certPool.AppendCertsFromPEM(rootCAs)

    tlsConfig := &tls.Config{
        Certificates:       []tls.Certificate{cert},
        RootCAs:            certPool,
        InsecureSkipVerify: false,
        MinVersion:         tls.VersionTLS12,
    }
    transport := &http.Transport{
        TLSClientConfig: tlsConfig,
    }
    return &http.Client{Transport: transport}, nil
}

3. Validate and Restrict Outbound Targets

Ensure that any user-provided URL is parsed and validated for scheme, host, and port. Reject private IP ranges and localhost unless explicitly required and safe.

import (
    "net"
    "net/url"
)

func isValidTarget(rawURL string) bool {
    parsed, err := url.Parse(rawURL)
    if err != nil || parsed.Scheme != "https" {
        return false
    }
    ip := net.ParseIP(parsed.Hostname())
    if ip != nil && (ip.IsPrivate() || ip.IsLoopback()) {
        return false
    }
    return true
}

Combine these techniques in Chi routes to ensure that even with mTLS, SSRF risks are minimized. middleBrick scans can help identify endpoints that accept untrusted URLs despite mTLS, providing findings with severity and remediation guidance.

Related CWEs: ssrf

CWE IDNameSeverity
CWE-918Server-Side Request Forgery (SSRF) CRITICAL
CWE-441Unintended Proxy or Intermediary (Confused Deputy) HIGH

Frequently Asked Questions

Can SSRF occur over mTLS if the server certificate is trusted internally?
Yes. If the server uses its trusted mTLS identity to make outbound requests and does not validate targets, SSRF can reach internal services that trust that certificate. mTLS protects inbound authentication but does not prevent a compromised server from making unauthorized outbound calls.
Does middleBrick detect SSRF in mTLS-enabled APIs?
Yes. middleBrick scans the unauthenticated attack surface and can identify endpoints that accept user-supplied URLs without proper validation, even when mTLS is used. Findings include severity and remediation guidance aligned with frameworks like OWASP API Top 10.