---
title: Validate mTLS Certificates Before Auth
impact: CRITICAL
impactDescription: ensures mutual identity verification between communicating services
tags: mtls, certificates, authentication, zero-trust, security, php
---

## Validate mTLS Certificates Before Auth

Mutual TLS (mTLS) provides strong authentication by requiring both the client and the server to present certificates. In PHP environments, the web server (Nginx/Apache) typically handles the handshake and passes certificate details to the application through server variables.

**Incorrect (implicitly trusting or skipping validation):**

```php
// VULNERABLE: Assuming any request reaching the script is authorized
function processInternalRequest() {
    // No check if the client certificate was actually validated by the web server
    $data = doTask(); 
}
```

**Correct (validating certificate variables in PHP):**

```php
// 1. Nginx Configuration required:
// ssl_verify_client on;
// fastcgi_param SSL_CLIENT_S_DN $ssl_client_s_dn;
// fastcgi_param SSL_CLIENT_VERIFY $ssl_client_verify;

// 2. PHP validation logic
function validateClientCert() {
    // Ensure the web server actually verified the certificate
    if (($_SERVER['SSL_CLIENT_VERIFY'] ?? '') !== 'SUCCESS') {
        header('HTTP/1.1 403 Forbidden');
        die("Mutual TLS authentication failed.");
    }

    // Validate the Distinguished Name (DN) or Common Name (CN)
    $clientDn = $_SERVER['SSL_CLIENT_S_DN'] ?? '';
    $allowedServices = ['CN=payment-service', 'CN=auth-service'];
    
    $isAuthorized = false;
    foreach ($allowedServices as $service) {
        if (strpos($clientDn, $service) !== false) {
            $isAuthorized = true;
            break;
        }
    }

    if (!$isAuthorized) {
        header('HTTP/1.1 403 Forbidden');
        die("Service certificate not authorized.");
    }
}
```

**Key Implementation steps:**
1. **Web Server**: Configure your reverse proxy (Nginx, Apache) to request client certificates and verify them against an internal Root CA.
2. **Environment**: Pass the verification status and client DN to PHP.
3. **Application**: Explicitly check `SSL_CLIENT_VERIFY` and optionally validate the specific identity (CN) of the calling service.

**Tools:** OpenSSL, Nginx `ssl_client_certificate`, HashiCorp Vault (for CA management), Istio/Linkerd
