HIGH server side template injectionactixmutual tls

Server Side Template Injection in Actix with Mutual Tls

Server Side Template Injection in Actix with Mutual Tls — how this specific combination creates or exposes the vulnerability

Server Side Template Injection (SSTI) occurs when an attacker can inject template expressions that are evaluated on the server. In Actix web applications that render dynamic content using server-side templates (for example via askama or tera), improperly sanitized inputs can lead to arbitrary code execution or information disclosure. When Mutual TLS (mTLS) is used, the server authenticates clients by requesting a client certificate. If the application uses the certificate fields (subject, common name, organization, or extensions) as template inputs without validation, the mTLS handshake—which supplies identity data into the application—becomes a vector for SSTI.

Consider an Actix service that terminates mTLS and then passes the peer’s distinguished name (DN) into a template for logging or status pages. If the DN is controlled by an authenticated (but malicious) client and the template engine evaluates expressions like {{ name }} without escaping, an attacker can inject template logic. For example, a crafted certificate with a Common Name such as {% import os %}{{ os.environ.get('SECRET') }} might cause the template engine to execute code if the engine supports arbitrary Python expressions (as with some Jinja2 or Tera configurations when macros or filters are exposed). The mTLS context supplies the tainted data, and the server processes it during rendering, creating a scenario where the trust boundary implied by mTLS is bypassed in the application logic.

Even when mTLS provides strong channel authentication, the application must still treat all client-supplied data—including certificate attributes—as untrusted. A misconfigured endpoint that exposes a debug or status route and renders certificate metadata in a template can disclose environment variables or trigger remote code execution. This is particularly relevant when developers assume mTLS alone suffices for integrity of identity data, leading to relaxed input validation. The 12 parallel security checks in middleBrick would flag this as an SSTI risk under Input Validation and identify unsafe consumption patterns under Unsafe Consumption, noting the presence of unvalidated mTLS-derived fields used in rendering.

Mutual Tls-Specific Remediation in Actix — concrete code fixes

To prevent SSTI when using mTLS in Actix, ensure certificate fields are treated as untrusted input and never passed directly into templates. Validate and sanitize any data derived from the client certificate, and use strict allowlists for expected values. Prefer structured metadata extraction with schema validation rather than raw DN string interpolation.

Below are concrete Actix examples that demonstrate safe handling of mTLS certificates.

Example 1: Extract and validate certificate fields in Actix middleware

use actix_web::{dev::ServiceRequest, Error, middleware::Next};
use actix_web_httpauth::extractors::Certificate;
use serde::{Deserialize, Serialize};
use regex::Regex;

#[derive(Debug, Deserialize, Serialize)]
struct ValidatedSubject {
    cn: String,
    org: Option,
}

async fn validate_certificate(cert: Option) -> Result {
    let cert = cert.ok_or_else(|| actix_web::error::ErrorUnauthorized("missing certificate"))?;
    let subject = cert.subject();
    // Extract CN safely; reject unexpected OUs or attributes
    let cn = subject.common_name().ok_or_else(|| actix_web::error::ErrorUnauthorized("missing CN"))?;
    let re = Regex::new(r"^[A-Za-z0-9._-]{1,64}$").unwrap();
    if !re.is_match(cn) {
        return Err(actix_web::error::ErrorBadRequest("invalid CN format"));
    }
    let org = subject.organization().first().map(|s| s.to_string()).filter(|s| !s.is_empty());
    Ok(ValidatedSubject { cn: cn.to_string(), org })
}

Example 2: Use validated data in handlers, avoiding direct template injection

use actix_web::{web, HttpResponse};
use askama::Template;

#[derive(Template)]
#[template(path = "status.html")]
struct StatusTemplate {
    cn: String,
    org: Option,
}

async fn status(
    validated: web::ReqData,
) -> HttpResponse {
    let body = StatusTemplate {
        cn: validated.cn.clone(),
        org: validated.org.clone(),
    };
    HttpResponse::Ok().content_type("text/html").body(body.render().unwrap_or_else(|_| "Error rendering".into()))
}

Example 3: Enforce mTLS at the Actix server level and reject unexpected extensions

use actix_web::web::Data;
use actix_web_httpauth::middleware::HttpAuthentication;
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};

fn create_ssl_config() -> SslAcceptor {
    let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
    builder.set_private_key_file("key.pem", SslFiletype::PEM).unwrap();
    builder.set_certificate_chain_file("cert.pem").unwrap();
    builder.set_client_ca_list(&[include_bytes("ca.pem")][..]);
    builder.set_verify(openssl::ssl::SslVerifyMode::PEER | openssl::ssl::SslVerifyMode::FAIL_IF_NO_PEER_CERT, 
        openssl::ssl::SslVerifyCallback::new(|_, _| true));
    builder.build()
}

// In main:
let ssl = create_ssl_config();
let server = actix_web::HttpServer::new(move || {
    let auth = HttpAuthentication::with_callback(|req, head| {
        // Use the validated extraction from Example 1
        validate_certificate(req.certificate()).into()
    });
    App::new()
        .wrap(auth)
        .app_data(web::ReqData::new(ValidatedSubject { cn: String::new(), org: None }))
        .service(web::resource("/status").to(status))
})
.bind_openssl("127.0.0.1:8443", ssl)?
.run();

By validating and whitelisting certificate fields, and by avoiding direct interpolation of raw DN strings into templates, you mitigate SSTI while preserving mTLS benefits. middleBrick can detect remaining risks by scanning endpoints that accept mTLS-authenticated requests and analyzing template usage patterns.

Frequently Asked Questions

Does mTLS prevent SSTI by itself?
No. Mutual TLS provides strong channel authentication and ensures the server knows the client’s identity, but it does not prevent the server from mishandling that identity data. If certificate fields are used unsafely in templates, SSTI can still occur.
Can middleBrick detect SSTI when mTLS is used?
Yes. middleBrick runs unauthenticated black-box checks and can identify SSTI patterns even when mTLS is used, by analyzing how identity data derived from certificates is consumed and whether it reaches template rendering.