Excessive Data Exposure with Mutual Tls
How Excessive Data Exposure Manifests in Mutual Tls
Excessive Data Exposure in Mutual Tls APIs occurs when the API returns more data than necessary, even with mutual authentication in place. The TLS handshake ensures both parties are authenticated, but it doesn't control what data flows over the established channel. This creates a false sense of security where developers assume mutual TLS alone provides sufficient data protection.
A common pattern appears in Spring Boot applications using Mutual Tls. Consider a REST controller that returns a User object:
@RestController
public class UserController {
@GetMapping("/api/user/{id}")
public User getUser(@PathVariable String id) {
return userService.findById(id); // Returns entire User object
}
}
The User class might contain sensitive fields:
public class User {
private String id;
private String username;
private String email;
private String ssn; // Social Security Number
private String creditCard; // Credit Card Number
private String address;
private String phoneNumber;
// getters and setters
}
Even with Mutual Tls authentication, this endpoint exposes all user data to any authenticated client. The TLS layer only verifies identity—it doesn't filter what data the authenticated client can access.
Another Mutual Tls-specific manifestation occurs in API responses that include internal system details. A payment processing API might return:
{
"transactionId": "abc123",
"amount": 100.00,
"status": "completed",
"merchantId": "merchant-456",
"internalProcessingCode": "PROC-789",
"databaseId": "db-123456",
"auditTrail": "[timestamp=2024-01-15T10:30:00Z, user=admin, action=processed]"
}
These internal details provide attackers with valuable information for reconnaissance, even when Mutual Tls is properly configured. The TLS authentication doesn't prevent data over-exposure.
Mutual Tls-Specific Detection
Detecting Excessive Data Exposure in Mutual Tls APIs requires examining both the authentication layer and the data returned. The first step is verifying Mutual Tls is actually enforced at the endpoint level:
// Spring Security configuration
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.requiresChannel()
.requestMatchers(r -> r.scheme().equals("https"))
.requiresSecure()
.and()
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/**").hasRole("CLIENT")
.anyRequest().authenticated()
)
.x509(auth -> auth
.subjectPrincipalRegex("CN=(.*?)(?:,|$)")
.and()
);
return http.build();
}
}
Using middleBrick to scan Mutual Tls APIs reveals excessive data exposure patterns. The scanner establishes a Mutual Tls connection using the client certificate and analyzes the response payload. For the User endpoint example, middleBrick would identify:
| Severity | Finding | Category | Recommendation |
|---|---|---|---|
| Medium | Excessive data exposure in /api/user/{id} | Data Exposure | Return only required fields |
The scanner specifically looks for patterns like:
- Fields containing "ssn", "credit", "card", "password", "secret"
- Large JSON objects with many properties when only 2-3 are needed
- Database identifiers and internal processing codes
- Audit trails and system metadata
middleBrick's Mutual Tls scanner tests unauthenticated endpoints by attempting connections without client certificates, then authenticated endpoints with valid certificates. This reveals whether authentication alone controls data access or if additional filtering is needed.
For OpenAPI spec analysis, middleBrick cross-references the spec's response schemas with actual runtime responses. If the spec defines a minimal response but the actual API returns more data, this discrepancy is flagged as a potential excessive data exposure issue.
Mutual Tls-Specific Remediation
Remediating Excessive Data Exposure in Mutual Tls APIs requires architectural changes beyond just authentication. The most effective approach is implementing Data Transfer Objects (DTOs) that define exactly what data should be exposed:
// DTO with only necessary fields
public class UserDTO {
private String id;
private String username;
private String email;
public UserDTO(User user) {
this.id = user.getId();
this.username = user.getUsername();
this.email = user.getEmail();
}
// getters only, no setters
}
// Updated controller
@RestController
public class UserController {
@GetMapping("/api/user/{id}")
public UserDTO getUser(@PathVariable String id) {
User user = userService.findById(id);
return new UserDTO(user); // Only returns safe fields
}
}
For Spring Boot applications using Mutual Tls, you can combine authentication with field-level filtering:
@RestController
public class SecureUserController {
@GetMapping("/api/user/{id}")
public Map;String, Object; getUser(@PathVariable String id, Principal principal) {
// Verify Mutual Tls authentication
if (!(principal instanceof X509Principal)) {
throw new UnauthorizedException("Mutual TLS required");
}
// Fetch user data
User user = userService.findById(id);
// Filter based on authenticated client
X509Principal x509 = (X509Principal) principal;
String clientCN = x509.getSubjectDN().getName();
Map;String, Object; response = new HashMap;;();
response.put("id", user.getId());
response.put("username", user.getUsername());
// Only show email to specific clients
if (clientCN.contains("trusted-client")) {
response.put("email", user.getEmail());
}
return response;
}
}
For Java applications using the javax.net.ssl library, implement certificate-based access control with data filtering:
import javax.net.ssl.X509KeyManager;
import java.security.Principal;
import java.security.cert.X509Certificate;
public class CertificateAwareFilter {
public Object filterUserData(X509Certificate[] certs, User user) {
// Verify Mutual Tls certificate
if (certs == null || certs.length == 0) {
throw new UnauthorizedException("No client certificate");
}
X509Certificate clientCert = certs[0];
String clientCN = getClientCN(clientCert);
// Apply data exposure rules based on certificate
Map;String, Object; filteredData = new HashMap;;();
filteredData.put("id", user.getId());
filteredData.put("username", user.getUsername());
// Role-based data exposure
if (isTrustedClient(clientCN)) {
filteredData.put("email", user.getEmail());
}
// Admin clients get more data
if (isAdminClient(clientCN)) {
filteredData.put("accountStatus", user.getAccountStatus());
}
return filteredData;
}
private String getClientCN(X509Certificate cert) {
String subjectDN = cert.getSubjectDN().getName();
for (String part : subjectDN.split(",")) {
if (part.trim().startsWith("CN=")) {
return part.substring(3).trim();
}
}
return "unknown";
}
}
The key principle: Mutual Tls provides authentication and encryption, but data exposure control must be implemented separately through proper response modeling and field filtering.
Related CWEs: propertyAuthorization
| CWE ID | Name | Severity |
|---|---|---|
| CWE-915 | Mass Assignment | HIGH |