HIGH clickjackingrocketbearer tokens

Clickjacking in Rocket with Bearer Tokens

Clickjacking in Rocket with Bearer Tokens — how this specific combination creates or exposes the vulnerability

Clickjacking is a client-side vulnerability where an attacker tricks a user into interacting with a hidden or disguised UI element inside an iframe. When Bearer Tokens are used for authentication in Rocket, a clickjacking-prone page can expose those tokens if the application embeds authenticated endpoints in iframes or fails to enforce frame-ancestor policies. Rocket is a web framework that encourages explicit route handling; however, if developers render authenticated views inside frames without setting appropriate CSP headers, a forged page can load those routes and capture actions or tokens leaked via side-channels such as reflected headers or cookies.

In this context, a Bearer Token is typically sent in the Authorization header (e.g., Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...). Even though the token itself is not directly accessible across origins due to same-origin policies and CORS, clickjacking can bypass user consent for actions that the authenticated user is authorized to perform. For example, an attacker may embed an authenticated Rocket endpoint that performs state-changing operations (like changing email or password) inside an invisible iframe and overlay interactive elements to induce clicks. If the application relies solely on the presence of a Bearer Token in headers for authorization and does not validate the Origin header or use anti-CSRF tokens for state-changing requests, the attack may succeed in performing unauthorized operations while appearing to come from the victim’s session.

Moreover, if Rocket APIs return sensitive data in responses and those endpoints are embeddable via iframe, an attacker can use CSS tricks to read reflected content or induce requests that reveal information. Although Bearer Tokens are not stored in local storage by the framework itself, client-side code may inadvertently expose them via JavaScript errors, referer headers, or logging when embedded in third-party frames. The combination of clickjacking techniques and Bearer Token-based authentication in Rocket becomes critical when the application does not implement frame-ancestor restrictions, lacks proper X-Frame-Options or Content-Security-Policy frame-ancestors directives, and does not validate the request origin for sensitive operations.

Consider an endpoint defined in Rocket that updates user settings and expects a Bearer Token in the Authorization header. If this route is inadvertently accessible via an embedded iframe and does not verify the Origin header, an attacker can craft a page that loads the endpoint in a hidden form, triggering a request with the user’s credentials. While Rocket’s guards and request guards help ensure authentication, they do not automatically protect against UI redressing unless the developer explicitly adds protections at the HTTP response level. Therefore, securing against clickjacking in Rocket with Bearer Tokens requires a defense-in-depth approach that combines frame-ancestor policies, anti-CSRF practices, and careful handling of authenticated routes exposed to browser embedding contexts.

Bearer Tokens-Specific Remediation in Rocket — concrete code fixes

Remediation focuses on preventing unauthorized embedding of authenticated endpoints and ensuring that requests with Bearer Tokens originate from trusted contexts. In Rocket, you can set HTTP headers to mitigate clickjacking and strengthen token handling. Below are concrete code examples that demonstrate how to configure your Rocket routes and guards to reduce risk.

1. Set Content-Security-Policy frame-ancestors

Prevent your authenticated pages from being embedded in iframes by adding a CSP header that restricts frame ancestors. This is effective across modern browsers and complements other defenses.

// In main.rs or a fairing
use rocket::http::Header;
use rocket::response::Response;

#[rocket::async_trait]
impl<'r> rocket::request::FromRequest<'r> for MyAuthGuard {
    type Error = ();
    async fn from_request(req: &'r Request<'_>) -> request::Outcome {
        // Your token validation logic
    }
}

#[get("/settings")]
async fn settings() -> &'static str {
    "Secure settings"
}

#[rocket::main]
async fn main() {
    rocket::build()
        .attach(rocket_cors::CorsFairing::new(|cors| {
            cors.set_allowed_origins(vec!["https://trusted.example.com"]);
        }))
        .mount("/", routes![settings])
        .launch()
        .await;
}

To set CSP directly, you can add a response guard that injects the header for sensitive routes:

use rocket::response::Responder;
use rocket::{Request, Response};

pub struct SecurityHeaders;

#[rocket::async_trait]
impl<'r> rocket::response::Responder<'r, 'static> for SecurityHeaders {
    fn respond_to(self, req: &Request) -> rocket::response::Result<'static> {
        let mut response = Response::build();
        response.set_header(rocket::http::Header::new(
            "Content-Security-Policy",
            "frame-ancestors 'self' https://trusted.example.com",
        ));
        response.set_header(rocket::http::Header::new(
            "X-Frame-Options",
            "DENY",
        ));
        Ok(response)
    }
}

2. Validate Origin and Referer for state-changing routes

For endpoints that modify state and accept Bearer Tokens, validate the Origin header to ensure requests come from your domain. This helps block cross-origin requests that could be induced via clickjacking.

use rocket::request::{Request, Outcome};
use rocket::http::Status;

fn validate_origin(req: &Request) -> bool {
    if let Some(origin) = req.headers().get_one("Origin") {
        origin == "https://your-app.com"
    } else if let Some(referer) = req.headers().get_one("Referer") {
        // Basic check; consider using a crate for URL parsing
        referer.starts_with("https://your-app.com")
    } else {
        false
    }
}

#[post("/update", data = &)
async fn update(body: String, req: &Request) -> Result {
    if !validate_origin(req) {
        return Err(Status::Forbidden);
    }
    // Process update with Bearer Token in Authorization header
    Ok("Updated".into())
}

3. Use anti-CSRF tokens for sensitive actions

Even with Bearer Tokens, adding anti-CSRF tokens for state-changing operations provides an additional layer of protection. Store a token in a secure, HttpOnly cookie and require it in headers or form fields.

use rocket::State;
use rocket::form::Form;

struct CsrfToken(String);

#[rocket::async_trait]
impl<'r> rocket::request::FromRequest<'r> for CsrfToken {
    type Error = ();
    async fn from_request(req: &'r Request<'_>) -> Outcome {
        // Validate token from header or form against session store
        Outcome::Success(CsrfToken("valid-token".into()))
    }
}

#[post("/action", data = &input)]
async fn perform_action(csrf: CsrfToken, input: Form) -> String {
    // Proceed with action
    "Action performed".into()
}

Combine these measures: set strict CSP and X-Frame-Options, validate Origin/Referer for sensitive endpoints, and use anti-CSRF tokens for state-changing operations. This reduces the attack surface for clickjacking against routes that rely on Bearer Tokens in Rocket applications.

Frequently Asked Questions

Can clickjacking with Bearer Tokens lead to token theft in Rocket?
Direct token theft via clickjacking is unlikely because browsers enforce same-origin policies for headers. However, clickjacking can induce authenticated actions that may change credentials or expose data. Mitigate by using CSP frame-ancestors, X-Frame-Options, and Origin validation.
Does middleBrick detect clickjacking risks in Rocket APIs with Bearer Tokens?
Yes, middleBrick scans unauthenticated attack surfaces and includes checks for security headers and authorization practices. It can identify missing CSP frame-ancestors and other misconfigurations that enable clickjacking, with prioritized findings and remediation guidance.