Clickjacking in Actix with Api Keys
Clickjacking in Actix with Api Keys — how this specific combination creates or exposes the vulnerability
Clickjacking is a client-side UI redress attack where an attacker tricks a user into interacting with a hidden or disguised element inside an invisible or embedded frame. In Actix applications that rely on API keys for authentication, clickjacking can undermine key-based protections when those keys are used to authorize sensitive actions rendered in the browser. If an Actix endpoint that validates an API key also renders state-changing UI in an <iframe> or embeds forms without anti-clickjacking defenses, an attacker can overlay invisible controls or proxy the authenticated session to perform actions the authorized user did not intend.
Consider an Actix service that uses an API key passed in a header for authorization and then displays a page with a “Revoke API Key” button served from the same domain. If this page is reachable inside an <iframe> on a malicious site and the application does not enforce X-Frame-Options or Content-Security-Policy (frame-ancestors), the button can be obscured beneath invisible layers. The user’s browser will send the API key in the request headers automatically, authorizing the malicious action. middleBrick’s 12 security checks, including the BFLA/Privilege Escalation and Property Authorization tests, can surface this by correlating unauthenticated UI endpoints with weak framing rules and exposed key-bearing requests.
Moreover, if the Actix app embeds an OpenAPI/Swagger UI generated from spec files without sandboxing the frame-ancestors directive, an attacker might embed the spec UI to explore authenticated endpoints and combine cross-site request forgery (CSRF) techniques with leaked API keys. Because API keys often grant broad access, the impact is elevated compared to session cookie-based clickjacking. middleBrick’s Input Validation and Data Exposure checks help detect whether UI pages leak keys in responses or allow embedding by inspecting CSP headers and frame policies. Even when API keys are stored server-side, client-side frames that perform key-authorized operations without additional integrity checks expose the application to this class of vulnerability.
Api Keys-Specific Remediation in Actix — concrete code fixes
Remediation centers on preventing your Actix app from being framed and ensuring API keys are never relied on solely for UI actions without additional protections. Use strict Content-Security-Policy frame-ancestors and X-Frame-Options headers, and avoid embedding sensitive endpoints in iframes. Below are concrete Actix examples showing how to set headers and structure handlers safely.
- Set CSP and X-Frame-Options in Actix middleware to disallow framing:
use actix_web::{web, App, HttpResponse, HttpServer, middleware::Logger};
use actix_web::http::header::{self, HeaderValue};
async fn index() -> HttpResponse {
let mut resp = HttpResponse::Ok()
.insert_header((header::CONTENT_SECURITY_POLICY, "default-src 'self'; frame-ancestors 'none'".to_string()))
.insert_header((header::X_FRAME_OPTIONS, HeaderValue::from_static("DENY")))
.body("API key protected page — cannot be embedded");
resp
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.wrap(Logger::default())
.route("/", web::get().to(index))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
- For endpoints that do need limited embedding (e.g., widgets), specify granular frame ancestors and require additional authentication beyond API keys:
use actix_web::{web, App, HttpResponse, HttpServer, HttpRequest};
use actix_web::http::header;
async fn widget(req: HttpRequest) -> HttpResponse {
// Require both CSP and a secondary check (e.g., same-origin AJAX with key)
let csp = "default-src 'self'; frame-ancestors 'self' https://trusted.example.com;";
let mut resp = HttpResponse::Ok()
.insert_header((header::CONTENT_SECURITY_POLICY, csp))
.insert_header((header::X_FRAME_OPTIONS, HeaderValue::from_static("SAMEORIGIN")))
.body("Trusted widget content");
resp
}
- Ensure API keys are not leaked to client-side code or logs, and require additional proof-of-work or re-authentication for sensitive operations, mitigating clickjacking even if a frame somehow bypasses CSP:
async fn revoke_key(req: HttpRequest, web::Json(payload): web::Json<RevokePayload>) -> HttpResponse {
// Validate API key server-side and require a secondary factor or re-auth token
let api_key = req.headers().get("X-API-Key").and_then(|v| v.to_str().ok());
if api_key != Some("valid_key") {
return HttpResponse::Forbidden().finish();
}
// Proceed with revocation...
HttpResponse::Ok().body("Key revoked")
}
By combining server-side header enforcement with secure key handling, Actix apps reduce the clickjacking surface even when API keys are used for authorization.