Bola Idor in Actix with Mutual Tls
Bola Idor in Actix with Mutual Tls — how this specific combination creates or exposes the vulnerability
Broken Object Level Authorization (BOLA) is an API security weakness where one user can access or modify another user's resources by manipulating object identifiers such as IDs, slugs, or keys. In Actix-web, this commonly arises when route handlers trust client-supplied identifiers without verifying that the authenticated actor owns the target resource. Adding mutual TLS (mTLS) changes the threat model but does not automatically prevent BOLA; it can inadvertently shift or expose authorization gaps when mTLS is used for coarse-grained identity and developers assume it replaces fine-grained access checks.
With mutual TLS in Actix, the server validates the client certificate during the TLS handshake and may extract subject fields (e.g., common name, organization, or custom OIDs) to identify the client. If the application then uses the certificate’s identity to authorize requests but continues to rely on user-supplied object IDs without scoping those IDs to the certificate’s principal, BOLA persists. An attacker who obtains a valid client certificate (e.g., through compromise or a stolen file) can iterate over other users’ IDs and access data because the server never revalidates ownership beyond the certificate label. Conversely, misconfigurations where mTLS is treated as sufficient authentication while route parameters remain weakly bound can create horizontal privilege escalation across tenants that should be isolated.
For example, consider an endpoint GET /users/{user_id}/profile in Actix where the handler trusts the mTLS certificate to identify the requester but does not ensure that {user_id} matches the certificate-bound user. A scanner testing unauthenticated attack surfaces can still probe these endpoints if the server accepts connections without client certs or if certificates are optional, revealing BOLA despite mTLS presence. OpenAPI specs with full $ref resolution highlight that the path parameter user_id is not constrained by security schemes tied to the mTLS identity, allowing cross-user traversal. Runtime findings may map to OWASP API Top 10 A01:2023 broken object level authorization and align with frameworks such as PCI-DSS and SOC2 controls that require scoping access to the resource owner.
Real-world attack patterns include enumeration of numeric or UUID identifiers, exploitation of predictable slugs, and abuse of shared group identifiers where mTLS provides group claims but the application fails to enforce group-level filtering. Because middleBrick tests unauthenticated attack surfaces and includes LLM/AI security probes, it can detect endpoints where mTLS is present yet BOLA remains, flagging missing ownership checks and excessive agency patterns such as unchecked function_call usage in downstream services that consume API outputs.
Mutual Tls-Specific Remediation in Actix — concrete code fixes
To fix BOLA in Actix while using mutual TLS, bind the identity from the certificate to the authorization logic and enforce resource ownership on every request. Do not rely on mTLS alone for object-level permissions; treat the certificate as an authentication signal and implement explicit authorization checks that scope data access to the authenticated principal.
Below are concrete, syntactically correct Actix-web examples that demonstrate how to extract certificate details, map them to a user identity, and enforce per-request ownership checks. These snippets assume you use rustls for TLS and that the client certificate contains a subject alternative name or distinguished name field that maps to a user ID (e.g., x509 subject CN or a custom OID).
1) Certificate extraction and identity mapping
use actix_web::{dev::ServiceRequest, Error, FromRequest, HttpRequest};
use actix_web_httpauth::extractors::AuthenticationError;
use openssl::x509::X509;
use std::future::{ready, Ready};
struct MtlsIdentity {
user_id: String,
}
impl FromRequest for MtlsIdentity {
type Error = Error;
type Future = Ready>;
fn from_request(req: &HttpRequest, _: &mut actix_web::dev::Payload) -> Self::Future {
// Extract peer certificate from request extensions (populated by rustls/openssl)
let cert = req.extensions()
.get::()
.ok_or(AuthenticationError::new()).map_err(|e| e.into())?;
// Map certificate subject to a user_id; example uses Common Name
let user_id = cert.subject_name()
.entries_by_nid(openssl::nid::COMMONNAME)
.next()
.and_then(|entry| entry.data().as_utf8_str().ok())
.map(|s| s.to_string())
.unwrap_or_else(|| "unknown".to_string());
ready(Ok(MtlsIdentity { user_id }))
}
}
2) Handler with BOLA check using mTLS identity
use actix_web::{web, HttpResponse};
use serde::Deserialize;
#[derive(Deserialize)]
struct ProfileParams {
user_id: String, // from path: /users/{user_id}/profile
}
async fn get_profile(
mtls_identity: MtlsIdentity,
params: web::Query,
) -> HttpResponse {
// BOLA protection: ensure the requested user_id matches the certificate-bound user_id
if mtls_identity.user_id != params.user_id {
return HttpResponse::forbidden().body("Access denied: insufficient permissions");
}
// Fetch profile for the authorized user from your data layer
// Example: let profile = user_repository.find_by_id(¶ms.user_id).unwrap_or_default();
HttpResponse::ok().json(serde_json::json!({ "profile": "data for {params.user_id}" }))
}
3) Scoping with tenant-aware checks (optional)
async fn get_tenant_resource(
mtls_identity: MtlsIdentity,
web::Path((tenant_id, resource_id)): web::Path<(String, String)>,
) -> HttpResponse {
// Ensure tenant and resource ownership align with the certificate identity
if !tenant_repository.user_has_access(&mtls_identity.user_id, &tenant_id, &resource_id) {
return HttpResponse::forbidden().body("Access denied: resource not owned or shared with user");
}
HttpResponse::ok().json(serde_json::json!({ "resource": "data" }))
}
Complementary protections include validating certificate revocation via CRL/OCSP where feasible, setting reasonable lifetimes for client certificates, and logging authorization failures for anomaly detection. middleBrick’s scans can verify that endpoints requiring mTLS also enforce object-level scoping, reducing the risk of BOLA even when certificates are used for transport-layer identity.
Related CWEs: bolaAuthorization
| CWE ID | Name | Severity |
|---|---|---|
| CWE-250 | Execution with Unnecessary Privileges | HIGH |
| CWE-639 | Insecure Direct Object Reference | CRITICAL |
| CWE-732 | Incorrect Permission Assignment | HIGH |