Clickjacking with Mutual Tls
How Clickjacking Manifests in Mutual Tls
Clickjacking attacks exploit the trust users place in their browsers by tricking them into clicking on hidden or disguised elements. In Mutual Tls environments, this vulnerability becomes particularly insidious because the presence of client certificates creates a false sense of security. Attackers can craft malicious pages that appear legitimate while silently performing actions on behalf of authenticated users.
The core mechanism involves loading a target Mutual Tls API endpoint within an iframe on a malicious page. Since Mutual Tls authentication occurs at the TLS layer, the client certificate is automatically presented to the server regardless of how the request originates. This means an attacker can create a convincing interface that overlays invisible iframes containing critical operations.
Consider a banking application using Mutual Tls for API access. An attacker might create a page offering "free credit score checks" that actually contains a hidden iframe pointing to the bank's transfer API. The user, already authenticated with their client certificate in their browser, clicks what they believe is a harmless button. Meanwhile, the invisible iframe executes a money transfer operation using their credentials.
<!DOCTYPE html>
<html>
<head>
<title>Free Credit Score Check</title>
<style>
/* Hide the malicious iframe */
iframe {
opacity: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/* Make the button cover the entire page */
.full-page-button {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(blue, green);
color: white;
font-size: 24px;
border: none;
cursor: pointer;
}
</style>
</head>
<body>
<iframe src="https://api.bank.com/transfer?amount=5000&to=attacker_account" seamless></iframe>
<button class="full-page-button" onclick="window.location.reload()">
Click to Check Your Free Credit Score
</button>
</body>
</html>In Mutual Tls scenarios, the attack becomes more dangerous because the client certificate eliminates the need for credential theft. The certificate is already present in the user's browser, and the TLS handshake automatically authenticates the request. This bypasses traditional defenses like CSRF tokens, which are designed to prevent unauthorized requests from other domains.
Mobile applications using Mutual Tls for API authentication face similar risks. A malicious app could overlay deceptive UI elements on top of legitimate application windows, capturing user interactions intended for secure operations. The Mutual Tls handshake ensures the request appears legitimate to the server, making detection difficult.
Mutual Tls-Specific Detection
Detecting clickjacking vulnerabilities in Mutual Tls environments requires examining both client-side and server-side configurations. The X-Frame-Options header serves as the primary defense mechanism, controlling whether a browser can render a page within a frame, iframe, embed, or object element.
Server-side detection involves scanning API endpoints for proper frame protection headers. A vulnerable Mutual Tls API endpoint might lack these critical security headers entirely:
curl -I https://api.example.com/secure-endpoint
HTTP/2 200
content-type: application/json
content-length: 1234
Compare this with a properly secured endpoint:
curl -I https://api.example.com/secure-endpoint
HTTP/2 200
content-type: application/json
content-length: 1234
x-frame-options: DENY
The X-Frame-Options header accepts three directives: DENY (never allow framing), SAMEORIGIN (allow framing only by pages from the same origin), and ALLOW-FROM uri (allow framing only from the specified URI).
For modern applications, Content-Security-Policy provides more granular control through the frame-ancestors directive:
Content-Security-Policy: frame-ancestors 'none'
Content-Security-Policy: frame-ancestors 'self' https://trusted.com
middleBrick's black-box scanning approach tests these headers automatically by attempting to load API endpoints within iframes and analyzing the response headers. The scanner checks for the presence and correctness of X-Frame-Options and Content-Security-Policy headers across all scanned endpoints.
Additional detection methods include examining API documentation and OpenAPI specifications for endpoints that should never be accessible via browser interfaces. Mutual Tls APIs handling sensitive operations like fund transfers, account modifications, or data exports should implement strict frame protection.
Mobile-specific detection requires analyzing application code for proper WebView configurations. Android applications should use:
WebView webView = new WebView(context);
WebSettings webSettings = webView.getSettings();
webSettings.setAllowFileAccessFromFileURLs(false);
webSettings.setAllowUniversalAccessFromFileURLs(false);
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
iOS applications should configure WKWebView appropriately:
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
configuration.mediaTypesRequiringUserActionForPlayback = YES;
configuration.applicationNameForUserAgent = @"MyApp";
middleBrick's scanning process includes these mobile-specific checks when analyzing API endpoints that might be consumed by mobile applications.
Mutual Tls-Specific Remediation
Implementing effective clickjacking protection in Mutual Tls environments requires a defense-in-depth approach. The primary mitigation involves configuring HTTP response headers to prevent unauthorized framing.
For web applications serving Mutual Tls APIs, implement X-Frame-Options at the application level:
// Node.js/Express example
app.use((req, res, next) => {
res.setHeader('X-Frame-Options', 'DENY');
next();
});
// For specific sensitive endpoints
app.post('/api/transfer', (req, res) => {
res.setHeader('X-Frame-Options', 'DENY');
// Transfer logic
});Java Spring Boot applications can use filters:
@Component
public class FrameOptionsFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (response instanceof HttpServletResponse) {
HttpServletResponse httpResp = (HttpServletResponse) response;
httpResp.setHeader("X-Frame-Options", "DENY");
}
chain.doFilter(request, response);
}
}Content-Security-Policy provides more modern and flexible protection:
// Apache .htaccess
<IfModule mod_headers.c>
Header always set Content-Security-Policy "frame-ancestors 'none'"
</IfModule>For Mutual Tls APIs that must be embedded in specific trusted contexts, use more permissive configurations:
Content-Security-Policy: frame-ancestors https://app.example.com https://admin.example.comMobile applications require additional considerations. Android's WebView provides extensive security configurations:
WebView webView = findViewById(R.id.webview);
WebSettings webSettings = webView.getSettings();
// Security configurations
webSettings.setAllowFileAccess(false);
webSettings.setAllowFileAccessFromFileURLs(false);
webSettings.setAllowUniversalAccessFromFileURLs(false);
webSettings.setJavaScriptEnabled(false); // Disable unless absolutely necessary
// Prevent tapjacking
webView.setFilterTouchesWhenObscured(true);
webView.setOnLongClickListener(v -> true); // Disable long press context menus
iOS applications should configure WKWebView with appropriate restrictions:
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.mediaTypesRequiringUserActionForPlayback = YES;
config.applicationNameForUserAgent = @"MySecureApp";
// Disable programmatic paste
config.userContentController = [[WKUserContentController alloc] init];
WKWebView *webView = [[WKWebView alloc] initWithFrame:frame configuration:config];
webView.scrollView.delegate = self; // Implement scroll view delegate to prevent overscroll
Additional hardening measures include implementing timing-based protections that detect rapid, sequential clicks that might indicate automated clickjacking attempts. Rate limiting at the API level can also help mitigate the impact of successful clickjacking attacks.
middleBrick's remediation guidance includes specific header configurations for different web frameworks and provides automated scanning to verify that implemented protections are effective. The scanner tests both the presence of security headers and their actual behavior by attempting to load endpoints within iframes from different origins.