HIGH sql injectionmutual tls

Sql Injection with Mutual Tls

How Sql Injection Manifests in Mutual Tls

SQL Injection vulnerabilities in Mutual TLS (mTLS) environments exploit the trust established between client and server certificates. While mTLS provides strong authentication, it doesn't prevent SQL injection in the application layer where certificate validation occurs.

Consider a typical mTLS setup where client certificates are validated before processing requests. An attacker with a compromised or fraudulently obtained certificate can still exploit SQL injection in the application logic:

func handleRequest(w http.ResponseWriter, r *http.Request) {
    // mTLS ensures client certificate is valid
    clientCert := r.TLS.PeerCertificates[0]
    
    // Vulnerable: certificate validation doesn't prevent SQL injection
    userID := r.FormValue("user_id")
    query := fmt.Sprintf("SELECT * FROM users WHERE id = %s AND cert_serial = '%s'", 
        userID, clientCert.SerialNumber)
    
    rows, err := db.Query(query)
    // ...
}

The mTLS layer only verifies the certificate chain and revocation status. It doesn't sanitize SQL inputs or prevent malicious query construction. An attacker with a valid certificate can still inject:

user_id=1 OR 1=1 --

This bypasses authorization checks even when mTLS authentication succeeds. The certificate validates, but the SQL query returns all user records.

Another mTLS-specific scenario involves certificate attribute injection. Some applications use certificate fields (like Common Name or Organizational Unit) in database queries:

String cn = cert.getSubjectX500Principal().getName();
String query = "SELECT * FROM users WHERE cert_cn = '" + cn + "'";

If the certificate's Common Name contains special characters or SQL syntax, injection becomes possible. An attacker can craft certificates with malicious values that survive mTLS validation but break SQL queries.

Mutual Tls-Specific Detection

Detecting SQL injection in mTLS environments requires testing both the certificate validation and application layers. middleBrick's black-box scanning approach is particularly effective here because it tests the actual attack surface without requiring source code access.

When scanning mTLS endpoints, middleBrick first establishes a valid TLS connection with client certificate authentication. The scanner then tests SQL injection patterns across all input parameters, including:

  • Query parameters that might be used in database lookups
  • Certificate-derived values used in application logic
  • Headers that pass through mTLS middleware
  • Request bodies that interact with database operations

middleBrick's SQL injection detection includes parameterized testing with common payloads:

user_id=1' OR '1'='1
user_id=1' UNION SELECT password FROM users --
user_id=1'; DROP TABLE users; --

The scanner monitors for SQL error responses, unexpected data exposure, or changes in response structure that indicate successful injection. For mTLS specifically, middleBrick tests whether certificate attributes are being incorporated into SQL queries and whether they're properly sanitized.

middleBrick also checks for timing-based SQL injection vulnerabilities, which are particularly relevant in mTLS environments where requests might be slower due to certificate validation overhead. The scanner uses techniques like:

user_id=1 AND SLEEP(5)
user_id=1' WAITFOR DELAY '00:00:05' --

These tests help identify blind SQL injection where error messages are suppressed but timing differences reveal vulnerability.

Mutual Tls-Specific Remediation

Remediating SQL injection in mTLS environments requires addressing both the database layer and how certificate data is handled. The foundation is always prepared statements with parameterized queries:

# Vulnerable - certificate data concatenated into SQL
cert_sn = r.TLS.PeerCertificates[0].SerialNumber
query = f"SELECT * FROM users WHERE cert_serial = '{cert_sn}' AND id = {user_id}"

# Secure - parameterized queries
query = "SELECT * FROM users WHERE cert_serial = ? AND id = ?"
cursor.execute(query, (cert_sn, user_id))

Even when using mTLS for authentication, never trust certificate fields as safe inputs. Always validate and sanitize certificate-derived data before using it in SQL queries:

const cert = req.socket.getPeerCertificate();
const certSn = cert.serialNumber;

// Validate certificate serial number format
if (!/^[0-9a-fA-F]+$/.test(certSn)) {
    throw new Error('Invalid certificate serial number');
}

// Use parameterized query
const query = 'SELECT * FROM users WHERE cert_serial = ? AND user_id = ?';
const params = [certSn, req.params.userId];

For mTLS-specific certificate handling, implement strict validation of certificate attributes before database use:

var cert = context.Connection.ClientCertificate;
var cn = cert.Subject?.Split(',').FirstOrDefault(s => s.Trim().StartsWith("CN="));

if (cn == null || !cn.StartsWith("CN=")) {
    throw new UnauthorizedAccessException();
}

var commonName = cn.Substring(3).Trim();

// Parameterized query with certificate data
using (var cmd = new SqlCommand("SELECT * FROM Users WHERE CertCN = @cn AND Id = @id", conn)) {
    cmd.Parameters.AddWithValue("@cn", commonName);
    cmd.Parameters.AddWithValue("@id", userId);
    // ...
}

Additionally, implement certificate field whitelisting to prevent injection through certificate attributes:

func validateCertField(field string) bool {
    // Allow only alphanumeric and basic punctuation
    matched, _ := regexp.MatchString(`^[a-zA-Z0-9 .-]+$`, field)
    return matched
}

certCN := clientCert.Subject.CommonName
if !validateCertField(certCN) {
    http.Error(w, "Invalid certificate", http.StatusBadRequest)
    return
}

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

Can mTLS prevent SQL injection attacks?
No, mTLS only provides authentication and encryption at the transport layer. It verifies client certificates but doesn't validate or sanitize SQL inputs. SQL injection occurs at the application layer where mTLS has no visibility. You still need proper input validation, parameterized queries, and other application security controls.
How does middleBrick detect SQL injection in mTLS APIs?
middleBrick establishes a valid mTLS connection using client certificate authentication, then systematically tests SQL injection payloads across all input vectors. The scanner checks for SQL error responses, data exposure, and timing differences that indicate successful injection. It also tests whether certificate-derived values are being incorporated into SQL queries and whether they're properly sanitized.