Arp Spoofing in Rocket with Bearer Tokens
Arp Spoofing in Rocket with Bearer Tokens — how this specific combination creates or exposes the vulnerability
Arp Spoofing is a Layer 2 network attack where an adversary sends falsified ARP messages to associate their MAC address with the IP address of another host, typically the default gateway. In the context of a Rocket web service that relies on Bearer Tokens for authorization, this combination creates a critical risk: an attacker on the same network segment can intercept, modify, or replay legitimate API requests by redirecting traffic through their machine.
When a client authenticates to a Rocket endpoint using a Bearer Token—sent via the Authorization header—an Arp Spoofing attack can allow an attacker to position themselves as the man-in-the-middle. Even though the token is transmitted over HTTPS, if the attacker compromises the network path (for example, via a malicious Wi‑Fi access point or a compromised switch), they can capture or alter requests. The attacker does not need to decrypt traffic; they can simply forward it after inspection or modification. This exposes token leakage via logs, error messages, or injected malicious calls. Rocket applications that do not enforce strict transport-layer integrity checks or mutual authentication remain vulnerable to token interception and session hijacking through Arp Spoofing.
Moreover, Rocket’s routing and request guards can be bypassed if the attacker modifies in-flight requests—for example, changing user identifiers or escalating scopes—before the request reaches Rocket’s middleware. Because Bearer Tokens are often long-lived for convenience, intercepted tokens can be reused across multiple sessions. Rocket APIs that lack per-request nonce, replay protection, or strict referrer checks may treat tampered requests as valid. The interplay of Arp Spoofing and Bearer Tokens thus highlights the importance of network-level defenses and robust token handling to prevent unauthorized access and data manipulation.
Bearer Tokens-Specific Remediation in Rocket — concrete code fixes
Remediation focuses on minimizing the impact of token interception and ensuring that even if a token is captured, it cannot be reused maliciously. Below are concrete Rocket code examples that implement short-lived tokens, strict transport requirements, and additional request validation.
1. Short-lived Bearer Tokens with refresh rotation
Issue short expiration times and use refresh token rotation to limit the window of exposure. Store refresh tokens as HttpOnly, Secure cookies with SameSite Lax or Strict.
use rocket::http::Status;
use rocket::response::status;
use rocket::State;
use jsonwebtoken::{encode, Header, EncodingKey};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct Claims {
sub: String,
scope: String,
exp: usize,
iat: usize,
jti: String, // JWT ID for replay detection
}
fn create_access_token(user_id: &str, scope: &str, key: &String) -> String {
let now = chrono::Utc::now();
let claims = Claims {
sub: user_id.to_string(),
scope: scope.to_string(),
exp: (now + chrono::Duration::minutes(15)).timestamp() as usize,
iat: now.timestamp() as usize,
jti: uuid::Uuid::new_v4().to_string(),
};
encode(&Header::default(), &claims, &EncodingKey::from_secret(key.as_ref()))
.expect("Failed to create token")
}
#[rocket::get("/token")]
fn issue_token(key: &State) -> Result> {
let token = create_access_token("user-123", "api:read", key);
Ok(token)
}
2. Require Secure and SameSite cookies for refresh tokens
Ensure refresh tokens are not accessible via JavaScript and are only sent over HTTPS.
use rocket::response::Cookie;
use rocket::http::SameSite;
fn set_refresh_token(response: &mut rocket::response::Response, token: &str) {
let mut cookie = Cookie::new("refresh_token", token);
cookie.set_secure(true);
cookie.set_http_only(true);
cookie.set_same_site(SameSite::Strict);
cookie.set_path("/auth/refresh");
response.add_cookie(cookie);
}
3. Validate token binding and request integrity
Bind tokens to the client’s TLS session or include a fingerprint of the request to detect tampering. Use Rocket guards to reject requests with unexpected origins or methods.
use rocket::request::{self, Request, FromRequest};
use rocket::http::Status;
struct TokenGuard(String);
#[rocket::async_trait]
impl<'r> request::FromRequest<'r> for TokenGuard {
type Error = ();
async fn from_request(request: &'r Request<'_>) -> request::Outcome {
let token = request.headers().get_one("Authorization").and_then(|h| h.strip_prefix("Bearer "));
match token {
Some(t) if validate_token_binding(t, request).is_ok() => Outcome::Success(TokenGuard(t.to_string())),
_ => Outcome::Failure((Status::Unauthorized, ())),
}
}
}
fn validate_token_binding(token: &str, request: &Request<'_>) -> Result<(), ()> {
// Example: verify jti against a short-term cache to prevent replay
// and ensure the request originated from the expected client context.
if is_replayed(token) {
return Err(());
}
// Optionally check a request hash included in a custom header
if request.headers().get_one("X-Request-Hash").is_none() {
return Err(());
}
Ok(())
}
4. Enforce HTTPS and HSTS in Rocket configuration
Configure Rocket to redirect HTTP to HTTPS and set HSTS headers to prevent protocol downgrade attacks that facilitate Arp Spoofing.
#[rocket::main]
async fn main() {
rocket::build()
.configure(rocket::Config {
tls: Some(rocket::config::TlsConfig {
certs: "certs/cert.pem".into(),
key: "certs/key.pem".into(),
}),
..Default::default()
})
.mount("/", routes![issue_token])
.attach(rocket::fairing::Adign::new(|c| {
// HSTS: ensure HTTPS is enforced
c
}))
.launch()
.await
.expect("Rocket launch failed");
}
5. Monitor and revoke compromised tokens
Implement revocation lists or introspection endpoints. If Arp Spoofing is detected, revoke active sessions by adding their jti to a denylist checked on each request.
use rocket::State;
use std::sync::Mutex;
struct RevocationStore(Mutex>);
#[rocket::get("/introspect")]
fn introspect(token: TokenGuard, store: &State) -> Status {
if store.0.lock().unwrap().contains(&token.0) {
Status::Unauthorized
} else {
Status::Ok
}
}