Zip Slip in Axum with Jwt Tokens
Zip Slip in Axum with Jwt Tokens — how this specific combination creates or exposes the vulnerability
Zip Slip is a path traversal vulnerability that occurs when an archive (for example, a ZIP file) is extracted without sanitizing member paths, allowing files to be written outside the intended directory. When this pattern is applied in an Axum application that handles JWT Tokens—such as accepting a signed token archive, a JWT compact serialization file, or a developer-supplied token bundle for introspection or key rotation—the unchecked extraction can place malicious files at arbitrary filesystem locations.
In practice, an endpoint that receives a JWT Tokens archive might use a library to unzip user-supplied input and then read or validate tokens from extracted files. If path traversal sequences like ../ are not removed or rejected, an attacker can craft an archive containing entries such as ../../../malicious/payload.rsa. During extraction, this can overwrite critical files, inject configuration or keys, or poison token caches used by the Axum JWT validation layer. Because Axum often integrates with JWT validation crates that load keys or verification material from files, an attacker who can influence what gets extracted may indirectly affect how JWT Tokens are verified—without ever sending a modified token directly to the runtime.
Even when Axum routes only validate JWT Tokens in memory, exposing an unauthenticated file extraction or introspection endpoint that processes archives creates a cross-contamination risk. For example, a compromised intermediate build artifact or a misconfigured staging endpoint might serve a ZIP containing both token material and malicious paths. The vulnerability is not in JWT Tokens themselves but in how Axum services that handle such archives manage file paths, temporary directories, and permissions. Because middleBrick detects risky patterns in unauthenticated scans—including SSRF-like behaviors and unsafe consumption of user-provided payloads—this class of issue is surfaced as a high-severity finding under Data Exposure and Unsafe Consumption checks.
Moreover, because middleBrick scans OpenAPI/Swagger specs with full $ref resolution and correlates definitions with runtime behavior, it can highlight discrepancies between documented JWT Tokens handling and actual file-system interactions. If your spec describes only JSON Web Token validation but the implementation also performs archive extraction, middleBrick will flag the expanded attack surface. This is especially important when endpoints accept JWT Tokens bundles or key sets via archives, which is common in federation or key-distribution workflows but dangerous without strict path controls.
Jwt Tokens-Specific Remediation in Axum — concrete code fixes
To remediate Zip Slip risks in Axum when dealing with JWT Tokens, ensure that any archive extraction normalizes and restricts paths, and avoid extracting user-controlled archives into shared or sensitive locations. Below are concrete, idiomatic Axum examples that show safe handling when JWT Tokens are involved.
Safe archive extraction with path sanitization
Use zip with strict path validation. Reject or sanitize entries that escape the intended directory.
use axum::{routing::post, Router};
use std::{fs::File, io::BufReader, path::Path};
use zip::ZipArchive;
async fn handle_token_archive(bytes: Vec<u8>) -> Result<(), String> {
let cursor = std::io::Cursor::new(bytes);
let mut archive = ZipArchive::new(cursor).map_err(|e| e.to_string())?;
let base = Path::new("./token_store"); // Intended, isolated directory
for i in 0..archive.len() {
let mut file = archive.by_index(i).map_err(|e| e.to_string())?;
let outpath = match file.enclosed_name() {
Some(path) => base.join(path),
None => return Err("Invalid path in archive".into()),
};
// Ensure the normalized path is still inside base
if !outpath.strip_prefix("./token_store").is_ok() {
return Err("Path traversal detected".into());
}
// If you expect JWT Tokens material, validate file name/content type
if outpath.extension().map_or(false, |e| e == "pem") {
let mut outfile = std::fs::File::create(&outpath).map_err(|e| e.to_string())?;
std::io::copy(&mut file.take(file.size()), &mut outfile).map_err(|e| e.to_string())?;
} else {
return Err("Unexpected file type in token archive".into());
}
}
Ok(())
}
#[tokio::main]
async fn main() {
let app = Router::new().route("/upload-tokens", post(|payload: axum::extract::Bytes| async move {
handle_token_archive(payload.to_vec()).await.map(|_| "OK").unwrap_or("Error")
}));
}
Reject unsigned or unexpected content types
When JWT Tokens are expected, validate MIME/content type and file extensions before writing to disk.
use axum::http::HeaderValue;
async fn validate_and_store_token_file(path: &std::path::Path, data: &[u8]) -> Result<(), String> {
if path.extension().and_then(|s| s.to_str()) != Some("pem") {
return Err("Only PEM files allowed".into());
}
// Optionally verify PEM header to ensure it contains key/certificate material
let content = std::str::from_utf8(data).map_err(|_| "Invalid UTF-8")?;
if !(content.starts_with("-----BEGIN CERTIFICATE-----") || content.starts_with("-----BEGIN PUBLIC KEY-----") || content.starts_with("-----BEGIN RSA PRIVATE KEY-----")) {
return Err("Invalid PEM header".into());
}
tokio::fs::write(path, data).await.map_err(|e| e.to_string())?;
Ok(())
}
Use in-memory JWT Tokens validation where possible
Prefer direct JWT Tokens validation via crates like jsonwebtoken and avoid writing sensitive material to disk. If you must store keys temporarily, use secure tempfiles with restricted permissions and clean up immediately.
use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation};
async fn validate_jwt_in_memory(token: &str) -> Result<jsonwebtoken::TokenData<Claims>, String> {
let decoding_key = DecodingKey::from_rsa_pem(include_bytes!("public_key.pem")).map_err(|e| e.to_string())?;
let mut validation = Validation::new(Algorithm::RS256);
validation.validate_exp = true;
decode::
By combining strict path controls, content validation, and minimizing filesystem exposure for JWT Tokens material, you reduce the Zip Slip attack surface while preserving legitimate token introspection workflows.